Merge branch 'master' into jwt-decode-verify
This commit is contained in:
commit
776974209e
2
.github/workflows/master.yml
vendored
2
.github/workflows/master.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
pages: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: Set node version
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
|
||||
2
.github/workflows/pull_requests.yml
vendored
2
.github/workflows/pull_requests.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: Set node version
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
|
||||
4
.github/workflows/releases.yml
vendored
4
.github/workflows/releases.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: Set node version
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
@ -110,7 +110,7 @@ jobs:
|
||||
needs: main
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
|
||||
- name: Set node version
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
|
||||
# This is because npm "chromedriver" package is not compatiable with all platforms
|
||||
# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
|
||||
FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:156b55f92e98ccd5ef49578a8cea0df4679826564bad1c9d4ef04462b9f0ded6 AS builder
|
||||
FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@ -27,7 +27,7 @@ RUN npm run build
|
||||
#########################################
|
||||
# Package static build files into nginx #
|
||||
#########################################
|
||||
FROM nginxinc/nginx-unprivileged:stable-alpine@sha256:fafa1102c789119971b3d83f9293f1ef5526bc73583a12e13ff5cd1299ed8b6c AS cyberchef
|
||||
FROM nginxinc/nginx-unprivileged:stable-alpine@sha256:458ecbec226a23120713b35945bcdf0d6e4ea5bbec60c149ce1deca5d264071b AS cyberchef
|
||||
|
||||
LABEL maintainer="GCHQ <oss@gchq.gov.uk>"
|
||||
|
||||
|
||||
272
package-lock.json
generated
272
package-lock.json
generated
@ -27,7 +27,7 @@
|
||||
"bootstrap-colorpicker": "^3.4.0",
|
||||
"bootstrap-material-design": "^4.1.3",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"bson": "^7.2.0",
|
||||
"bson": "^7.3.0",
|
||||
"buffer": "^6.0.3",
|
||||
"cbor": "10.0.12",
|
||||
"chi-squared": "^1.1.0",
|
||||
@ -85,7 +85,7 @@
|
||||
"path": "^0.12.7",
|
||||
"popper.js": "^1.16.1",
|
||||
"process": "^0.11.10",
|
||||
"protobufjs": "^8.6.4",
|
||||
"protobufjs": "^8.6.5",
|
||||
"punycode.js": "^2.3.1",
|
||||
"qr-image": "^3.2.0",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
@ -94,7 +94,7 @@
|
||||
"snackbarjs": "^1.1.0",
|
||||
"sortablejs": "^1.15.7",
|
||||
"split.js": "^1.6.5",
|
||||
"sql-formatter": "^15.8.1",
|
||||
"sql-formatter": "^15.8.2",
|
||||
"ssdeep.js": "0.0.3",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"tesseract.js": "^7.0.0",
|
||||
@ -102,7 +102,7 @@
|
||||
"unorm": "^1.6.0",
|
||||
"url": "^0.11.4",
|
||||
"utf8": "^3.0.0",
|
||||
"uuid": "^14.0.0",
|
||||
"uuid": "^14.0.1",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xpath": "0.0.34",
|
||||
"xregexp": "^5.1.2",
|
||||
@ -114,13 +114,13 @@
|
||||
"@babel/plugin-transform-runtime": "^7.29.7",
|
||||
"@babel/preset-env": "^7.29.7",
|
||||
"@babel/runtime": "^7.29.7",
|
||||
"@codemirror/commands": "^6.10.3",
|
||||
"@codemirror/commands": "^6.10.4",
|
||||
"@codemirror/language": "^6.12.3",
|
||||
"@codemirror/search": "^6.7.1",
|
||||
"@codemirror/state": "^6.5.4",
|
||||
"@codemirror/view": "^6.43.1",
|
||||
"@puppeteer/browsers": "3.0.4",
|
||||
"autoprefixer": "^10.5.0",
|
||||
"@codemirror/view": "^6.43.2",
|
||||
"@puppeteer/browsers": "3.0.5",
|
||||
"autoprefixer": "^10.5.1",
|
||||
"babel-loader": "^10.1.1",
|
||||
"base64-loader": "^1.0.0",
|
||||
"chromedriver": "^148.0.4",
|
||||
@ -133,7 +133,7 @@
|
||||
"css-loader": "^7.1.4",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-jsdoc": "^50.8.0",
|
||||
"globals": "^17.6.0",
|
||||
"globals": "^17.7.0",
|
||||
"grunt": "^1.6.2",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-concurrent": "^3.0.0",
|
||||
@ -1848,14 +1848,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/commands": {
|
||||
"version": "6.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.3.tgz",
|
||||
"integrity": "sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==",
|
||||
"version": "6.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.4.tgz",
|
||||
"integrity": "sha512-Ryk9y9T0FFVF0cUGhAknveAyUOl/A1qReTFi+qPKtOh2Z9F4AUBz3XOrYD4ZEgZirdugVzHvd/2/Wcwy5OliTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.6.0",
|
||||
"@codemirror/state": "^6.7.0",
|
||||
"@codemirror/view": "^6.27.0",
|
||||
"@lezer/common": "^1.1.0"
|
||||
}
|
||||
@ -1888,9 +1888,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.6.0.tgz",
|
||||
"integrity": "sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==",
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.0.tgz",
|
||||
"integrity": "sha512-Zbl9NyscLMZkfXPQnNAIIAFftidrA1UbcJEIMp24C0Bukc2I5T8wJS0wsXYsnDOqCFJUeJ1BITGNs5CqPDSmSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -1898,13 +1898,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "6.43.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.1.tgz",
|
||||
"integrity": "sha512-+BIjw/AG3tDQ4pJgTLPYdAW25eDE66YsvM4LKyVPgGzVgZ4a9Wj1SRX8kPVKgBDdPt8oHtZ15F0qx7p0oOHdHw==",
|
||||
"version": "6.43.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.2.tgz",
|
||||
"integrity": "sha512-8kU6WNRYBKV9Sw3cxNz+uSvUvx3tt+1qgupGFPubnbLFDHOgh5qQdIGmXcD7bkA/PROK6LDKVhKMpcY7H++Amg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.6.0",
|
||||
"@codemirror/state": "^6.7.0",
|
||||
"crelt": "^1.0.6",
|
||||
"style-mod": "^4.1.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
@ -4417,14 +4417,14 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@puppeteer/browsers": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.4.tgz",
|
||||
"integrity": "sha512-HGM8iAmGTf+Y7t0373szVbTmt3d7vPkYL/1bpOkOFO0YUYLgSeuYBCzESklogNPvOBnZ/MRD5f07OkpqH1trtA==",
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-3.0.5.tgz",
|
||||
"integrity": "sha512-xYXNuEQmHNIPWWcbL/skf2KF7seyp7c1xmKFRk3wmdFx7VwBsKVrtOLKs8ecaezsKPsWeF1YsgwIiElAscaryA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"modern-tar": "^0.7.6",
|
||||
"yargs": "^17.7.2"
|
||||
"yargs": "^18.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"browsers": "lib/main-cli.js"
|
||||
@ -4441,48 +4441,132 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/ansi-regex": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/ansi-styles": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
|
||||
"integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
"string-width": "^7.2.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"wrap-ansi": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"node_modules/@puppeteer/browsers/node_modules/emoji-regex": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
|
||||
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/string-width": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
|
||||
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
"emoji-regex": "^10.3.0",
|
||||
"get-east-asian-width": "^1.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/strip-ansi": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
|
||||
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/wrap-ansi": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
|
||||
"integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.2.1",
|
||||
"string-width": "^7.0.0",
|
||||
"strip-ansi": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/yargs": {
|
||||
"version": "18.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",
|
||||
"integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^9.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"string-width": "^7.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^22.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"version": "22.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
|
||||
"integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": "^20.19.0 || ^22.12.0 || >=23"
|
||||
}
|
||||
},
|
||||
"node_modules/@testim/chrome-version": {
|
||||
@ -5531,9 +5615,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz",
|
||||
"integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==",
|
||||
"version": "10.5.1",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.1.tgz",
|
||||
"integrity": "sha512-jwM2pcTuCWUoN70FEvf5XrXyDbUgRURK4FnU8v0jWZZYU/KkVvN9T33mu1sVLFY9JW3kTWzKheEpn6xYLRc/VA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -5551,8 +5635,8 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.28.2",
|
||||
"caniuse-lite": "^1.0.30001787",
|
||||
"browserslist": "^4.28.4",
|
||||
"caniuse-lite": "^1.0.30001799",
|
||||
"fraction.js": "^5.3.4",
|
||||
"picocolors": "^1.1.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
@ -5725,9 +5809,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.10.19",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.19.tgz",
|
||||
"integrity": "sha512-qCkNLi2sfBOn8XhZQ0FXsT1Ki/Yo5P90hrkRamVFRS7/KV9hpfA4HkoWNU152+8w0zPjnxo5psx5NL3PSGgv5g==",
|
||||
"version": "2.10.40",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.40.tgz",
|
||||
"integrity": "sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@ -6259,9 +6343,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.28.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
|
||||
"integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
|
||||
"version": "4.28.4",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
|
||||
"integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -6279,10 +6363,10 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.10.12",
|
||||
"caniuse-lite": "^1.0.30001782",
|
||||
"electron-to-chromium": "^1.5.328",
|
||||
"node-releases": "^2.0.36",
|
||||
"baseline-browser-mapping": "^2.10.38",
|
||||
"caniuse-lite": "^1.0.30001799",
|
||||
"electron-to-chromium": "^1.5.376",
|
||||
"node-releases": "^2.0.48",
|
||||
"update-browserslist-db": "^1.2.3"
|
||||
},
|
||||
"bin": {
|
||||
@ -6293,9 +6377,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bson": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-7.2.0.tgz",
|
||||
"integrity": "sha512-YCEo7KjMlbNlyHhz7zAZNDpIpQbd+wOEHJYezv0nMYTn4x31eIUM2yomNNubclAt63dObUzKHWsBLJ9QcZNSnQ==",
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-7.3.0.tgz",
|
||||
"integrity": "sha512-WmjjMEwFwZHmGnAb7wn90MhkiT+mTm4x/rLj7dvAPWfwnVWDXhLun2e+UM88MJoDGW624yzZglVX/zTBy9ZZMw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
@ -6474,9 +6558,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001788",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz",
|
||||
"integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==",
|
||||
"version": "1.0.30001799",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
|
||||
"integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -8692,9 +8776,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.339",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.339.tgz",
|
||||
"integrity": "sha512-Is+0BBHJ4NrdpAYiperrmp53pLywG/yV/6lIMTAnhxvzj/Cmn5Q/ogSHC6AKe7X+8kPLxxFk0cs5oc/3j/fxIg==",
|
||||
"version": "1.5.379",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.379.tgz",
|
||||
"integrity": "sha512-v/qV5aV5EUA2pGilzUCq5/eyOloZAqDZBu9UMBIzgPpLlprjSR6zswsWBTv0KpqxLGUAZEwhO95ZCt7srymNVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@ -10027,6 +10111,19 @@
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/get-east-asian-width": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
|
||||
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-func-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
|
||||
@ -10236,9 +10333,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "17.6.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz",
|
||||
"integrity": "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==",
|
||||
"version": "17.7.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz",
|
||||
"integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -13814,11 +13911,14 @@
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.36",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz",
|
||||
"integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==",
|
||||
"version": "2.0.50",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.50.tgz",
|
||||
"integrity": "sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/nodom": {
|
||||
"version": "2.4.0",
|
||||
@ -15086,9 +15186,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/protobufjs": {
|
||||
"version": "8.6.4",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.6.4.tgz",
|
||||
"integrity": "sha512-/+XMv9JalknuncEJSwsyEVlwcxVLKx2iaoSUXFZA86MJkdqyOdfrlB1sB7S6aKyUk9tl20YY+SgQe5J2sJHTcg==",
|
||||
"version": "8.6.5",
|
||||
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.6.5.tgz",
|
||||
"integrity": "sha512-zeE5LPpencAGXvsxyOYmEgJhxzHY8IsmPAFzstZVhDSVT8QH03q6gMZwZRaQGApevZbAL6u28ugs4CC+YKB2jQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"long": "^5.3.2"
|
||||
@ -16774,9 +16874,9 @@
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/sql-formatter": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.8.1.tgz",
|
||||
"integrity": "sha512-nT2r90kTEYBuse9fe4r1Rp78v1mOBD35KsGc07Vo9eQSVa1TcTSnCS0zouf6BCmdzvmqBsBW+cYuBoYkHO/OWg==",
|
||||
"version": "15.8.2",
|
||||
"resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.8.2.tgz",
|
||||
"integrity": "sha512-kTYRg5FIcvsDtYUG2Qn9pYT6xKwiLJN5TTIvc5Mur6hIg4pSfdpHu8Yyu5bqESLHnVM3mXzD446cb2+uEaKZXg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
@ -17858,9 +17958,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
|
||||
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
|
||||
"version": "14.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz",
|
||||
"integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
|
||||
18
package.json
18
package.json
@ -44,13 +44,13 @@
|
||||
"@babel/plugin-transform-runtime": "^7.29.7",
|
||||
"@babel/preset-env": "^7.29.7",
|
||||
"@babel/runtime": "^7.29.7",
|
||||
"@codemirror/commands": "^6.10.3",
|
||||
"@codemirror/commands": "^6.10.4",
|
||||
"@codemirror/language": "^6.12.3",
|
||||
"@codemirror/search": "^6.7.1",
|
||||
"@codemirror/state": "^6.5.4",
|
||||
"@codemirror/view": "^6.43.1",
|
||||
"@puppeteer/browsers": "3.0.4",
|
||||
"autoprefixer": "^10.5.0",
|
||||
"@codemirror/view": "^6.43.2",
|
||||
"@puppeteer/browsers": "3.0.5",
|
||||
"autoprefixer": "^10.5.1",
|
||||
"babel-loader": "^10.1.1",
|
||||
"base64-loader": "^1.0.0",
|
||||
"chromedriver": "^148.0.4",
|
||||
@ -63,7 +63,7 @@
|
||||
"css-loader": "^7.1.4",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-jsdoc": "^50.8.0",
|
||||
"globals": "^17.6.0",
|
||||
"globals": "^17.7.0",
|
||||
"grunt": "^1.6.2",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-concurrent": "^3.0.0",
|
||||
@ -111,7 +111,7 @@
|
||||
"bootstrap-colorpicker": "^3.4.0",
|
||||
"bootstrap-material-design": "^4.1.3",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
"bson": "^7.2.0",
|
||||
"bson": "^7.3.0",
|
||||
"buffer": "^6.0.3",
|
||||
"cbor": "10.0.12",
|
||||
"chi-squared": "^1.1.0",
|
||||
@ -169,7 +169,7 @@
|
||||
"path": "^0.12.7",
|
||||
"popper.js": "^1.16.1",
|
||||
"process": "^0.11.10",
|
||||
"protobufjs": "^8.6.4",
|
||||
"protobufjs": "^8.6.5",
|
||||
"punycode.js": "^2.3.1",
|
||||
"qr-image": "^3.2.0",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
@ -178,7 +178,7 @@
|
||||
"snackbarjs": "^1.1.0",
|
||||
"sortablejs": "^1.15.7",
|
||||
"split.js": "^1.6.5",
|
||||
"sql-formatter": "^15.8.1",
|
||||
"sql-formatter": "^15.8.2",
|
||||
"ssdeep.js": "0.0.3",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"tesseract.js": "^7.0.0",
|
||||
@ -186,7 +186,7 @@
|
||||
"unorm": "^1.6.0",
|
||||
"url": "^0.11.4",
|
||||
"utf8": "^3.0.0",
|
||||
"uuid": "^14.0.0",
|
||||
"uuid": "^14.0.1",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xpath": "0.0.34",
|
||||
"xregexp": "^5.1.2",
|
||||
|
||||
@ -292,11 +292,7 @@ class Dish {
|
||||
and reinitialise it as a BigNumber object.
|
||||
*/
|
||||
if (Object.keys(this.value).sort().equals(["c", "e", "s"])) {
|
||||
const temp = new BigNumber();
|
||||
temp.c = this.value.c;
|
||||
temp.e = this.value.e;
|
||||
temp.s = this.value.s;
|
||||
this.value = temp;
|
||||
this.value = new BigNumber({ s: this.value.s, e: this.value.e, c: this.value.c, _isBigNumber: true});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -241,9 +241,11 @@ class Recipe {
|
||||
// Cannot rely on `err instanceof OperationError` here as extending
|
||||
// native types is not fully supported yet.
|
||||
dish.set(err.message, "string");
|
||||
this.lastRunOp = null;
|
||||
return i;
|
||||
} else if (err instanceof DishError || err?.type === "DishError") {
|
||||
dish.set(err.message, "string");
|
||||
this.lastRunOp = null;
|
||||
return i;
|
||||
} else {
|
||||
const e = typeof err == "string" ? { message: err } : err;
|
||||
|
||||
@ -108,14 +108,17 @@ export function mean(data) {
|
||||
* @returns {BigNumber}
|
||||
*/
|
||||
export function median(data) {
|
||||
if ((data.length % 2) === 0 && data.length > 0) {
|
||||
if (data.length > 0) {
|
||||
data.sort(function(a, b) {
|
||||
return a.minus(b);
|
||||
});
|
||||
const first = data[Math.floor(data.length / 2)];
|
||||
const second = data[Math.floor(data.length / 2) - 1];
|
||||
return mean([first, second]);
|
||||
} else {
|
||||
|
||||
if ((data.length % 2) === 0) {
|
||||
const first = data[Math.floor(data.length / 2)];
|
||||
const second = data[Math.floor(data.length / 2) - 1];
|
||||
return mean([first, second]);
|
||||
}
|
||||
|
||||
return data[Math.floor(data.length / 2)];
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,20 +33,29 @@ export default class TLVParser {
|
||||
* @returns {number}
|
||||
*/
|
||||
getLength() {
|
||||
let bytesInLength = this.bytesInLength;
|
||||
let bigEndian = false;
|
||||
|
||||
if (this.basicEncodingRules) {
|
||||
const bit = this.input[this.location];
|
||||
if (bit & 0x80) {
|
||||
this.bytesInLength = bit & ~0x80;
|
||||
const firstLengthByte = this.input[this.location];
|
||||
this.location++;
|
||||
|
||||
if (firstLengthByte & 0x80) {
|
||||
bytesInLength = firstLengthByte & ~0x80;
|
||||
bigEndian = true;
|
||||
} else {
|
||||
this.location++;
|
||||
return bit & ~0x80;
|
||||
return firstLengthByte & ~0x80;
|
||||
}
|
||||
}
|
||||
|
||||
let length = 0;
|
||||
|
||||
for (let i = 0; i < this.bytesInLength; i++) {
|
||||
length += this.input[this.location] * Math.pow(Math.pow(2, 8), i);
|
||||
for (let i = 0; i < bytesInLength; i++) {
|
||||
if (bigEndian) {
|
||||
length = (length << 8) + this.input[this.location];
|
||||
} else {
|
||||
length += this.input[this.location] * Math.pow(Math.pow(2, 8), i);
|
||||
}
|
||||
this.location++;
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,11 @@ class BLAKE3 extends Operation {
|
||||
this.args = [
|
||||
{
|
||||
"name": "Size (bytes)",
|
||||
"type": "number"
|
||||
"type": "number",
|
||||
"value": 16,
|
||||
"min": 1,
|
||||
"max": 65535, // arbitrary limit to prevent resource exhaustion
|
||||
"integer": true,
|
||||
}, {
|
||||
"name": "Key",
|
||||
"type": "string",
|
||||
|
||||
@ -27,7 +27,10 @@ class BitShiftLeft extends Operation {
|
||||
{
|
||||
"name": "Amount",
|
||||
"type": "number",
|
||||
"value": 1
|
||||
"value": 1,
|
||||
"min": 0,
|
||||
"max": 7,
|
||||
"integer": true,
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@ -45,12 +45,15 @@ class DechunkHTTPResponse extends Operation {
|
||||
const lineEndingsLength = lineEndings.length;
|
||||
let chunkSize = parseInt(input.slice(0, chunkSizeEnd), 16);
|
||||
while (!isNaN(chunkSize)) {
|
||||
if (chunkSize === 0) {
|
||||
break;
|
||||
}
|
||||
chunks.push(input.slice(chunkSizeEnd, chunkSize + chunkSizeEnd));
|
||||
input = input.slice(chunkSizeEnd + chunkSize + lineEndingsLength);
|
||||
chunkSizeEnd = input.indexOf(lineEndings) + lineEndingsLength;
|
||||
chunkSize = parseInt(input.slice(0, chunkSizeEnd), 16);
|
||||
}
|
||||
return chunks.join("") + input;
|
||||
return chunks.join("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -51,9 +51,10 @@ class FromBase extends Operation {
|
||||
if (number.length === 1) return result;
|
||||
|
||||
// Fractional part
|
||||
const radixBN = new BigNumber(radix);
|
||||
for (let i = 0; i < number[1].length; i++) {
|
||||
const digit = new BigNumber(number[1][i], radix);
|
||||
result += digit.div(Math.pow(radix, i+1));
|
||||
result = result.plus(digit.div(radixBN.pow(i + 1)));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@ -74,6 +74,10 @@ class GenerateImage extends Operation {
|
||||
Bits: 1 / 8,
|
||||
};
|
||||
|
||||
if (!Object.hasOwn(bytePerPixelMap, mode)) {
|
||||
throw new OperationError(`Unsupported Mode: (${mode})`);
|
||||
}
|
||||
|
||||
const bytesPerPixel = bytePerPixelMap[mode];
|
||||
|
||||
if (bytesPerPixel > 0 && input.length % bytesPerPixel !== 0) {
|
||||
|
||||
@ -74,13 +74,11 @@ class Gzip extends Operation {
|
||||
}
|
||||
if (comment.length) {
|
||||
options.flags.comment = true;
|
||||
options.flags.fcomment = true;
|
||||
options.comment = comment;
|
||||
}
|
||||
const gzipObj = new Zlib.Gzip(new Uint8Array(input), options);
|
||||
const compressed = new Uint8Array(gzipObj.compress());
|
||||
if (options.flags.comment && !(compressed[3] & 0x10)) {
|
||||
compressed[3] |= 0x10;
|
||||
}
|
||||
return compressed.buffer;
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +51,18 @@ class JsonataQuery extends Operation {
|
||||
|
||||
try {
|
||||
const expression = jsonata(query);
|
||||
// Override built-in base64 functions which fail in Web Worker
|
||||
// context where `window` is undefined. The jsonata library falls
|
||||
// back to `global.Buffer` which also does not exist in workers.
|
||||
// `atob`/`btoa` are available in both browser and worker scopes.
|
||||
expression.registerFunction("base64decode", (str) => {
|
||||
if (typeof str === "undefined") return undefined;
|
||||
return atob(str);
|
||||
}, "<s-:s>");
|
||||
expression.registerFunction("base64encode", (str) => {
|
||||
if (typeof str === "undefined") return undefined;
|
||||
return btoa(str);
|
||||
}, "<s-:s>");
|
||||
result = await expression.evaluate(jsonObj);
|
||||
} catch (err) {
|
||||
throw new OperationError(
|
||||
|
||||
@ -87,7 +87,7 @@ class MIMEDecoding extends Operation {
|
||||
end = cur + j + "?=".length;
|
||||
|
||||
if (encoding.toLowerCase() === "b") {
|
||||
text = fromBase64(text);
|
||||
text = fromBase64(text, undefined, "byteArray");
|
||||
} else if (encoding.toLowerCase() === "q") {
|
||||
text = this.parseQEncodedWord(text);
|
||||
} else {
|
||||
|
||||
@ -31,7 +31,8 @@ class PseudoRandomNumberGenerator extends Operation {
|
||||
{
|
||||
"name": "Number of bytes",
|
||||
"type": "number",
|
||||
"value": 32
|
||||
"value": 32,
|
||||
"min": 1
|
||||
},
|
||||
{
|
||||
"name": "Output as",
|
||||
|
||||
@ -75,9 +75,16 @@ class SetDifference extends Operation {
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
runSetDifference(a, b) {
|
||||
const excluded = new Set(b);
|
||||
const seen = new Set();
|
||||
|
||||
return a
|
||||
.filter((item) => {
|
||||
return b.indexOf(item) === -1;
|
||||
if (excluded.has(item) || seen.has(item)) {
|
||||
return false;
|
||||
}
|
||||
seen.add(item);
|
||||
return true;
|
||||
})
|
||||
.join(this.itemDelimiter);
|
||||
}
|
||||
|
||||
@ -75,9 +75,16 @@ class SetIntersection extends Operation {
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
runIntersect(a, b) {
|
||||
const included = new Set(b);
|
||||
const seen = new Set();
|
||||
|
||||
return a
|
||||
.filter((item) => {
|
||||
return b.indexOf(item) > -1;
|
||||
if (!included.has(item) || seen.has(item)) {
|
||||
return false;
|
||||
}
|
||||
seen.add(item);
|
||||
return true;
|
||||
})
|
||||
.join(this.itemDelimiter);
|
||||
}
|
||||
|
||||
@ -71,6 +71,16 @@ class ShowOnMap extends Operation {
|
||||
}
|
||||
latLong = latLong.replace(/[,]$/, "");
|
||||
latLong = latLong.replace(/°/g, "");
|
||||
|
||||
// The map requires a latitude and longitude pair. If the conversion only produced a
|
||||
// single value (e.g. because the chosen input delimiter didn't match the input), bail
|
||||
// out with a helpful message rather than passing it on to the map, which would throw an
|
||||
// uncaught TypeError in the browser.
|
||||
const coords = latLong.split(",").map(v => v.trim());
|
||||
if (coords.length !== 2 || coords.some(v => v === "" || isNaN(Number(v)))) {
|
||||
throw new OperationError(`Could not show coordinates '${latLong}' on the map. Expected a latitude and longitude pair - check that the input format and delimiter are correct.`);
|
||||
}
|
||||
|
||||
return latLong;
|
||||
}
|
||||
return input;
|
||||
|
||||
@ -28,7 +28,10 @@ class ToBase extends Operation {
|
||||
{
|
||||
"name": "Radix",
|
||||
"type": "number",
|
||||
"value": 36
|
||||
"value": 36,
|
||||
"min": 2,
|
||||
"max": 36,
|
||||
"integer": true,
|
||||
}
|
||||
];
|
||||
}
|
||||
@ -43,9 +46,6 @@ class ToBase extends Operation {
|
||||
throw new OperationError("Error: Input must be a number");
|
||||
}
|
||||
const radix = args[0];
|
||||
if (radix < 2 || radix > 36) {
|
||||
throw new OperationError("Error: Radix argument must be between 2 and 36");
|
||||
}
|
||||
return input.toString(radix);
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,10 @@ class ToBinary extends Operation {
|
||||
{
|
||||
"name": "Byte Length",
|
||||
"type": "number",
|
||||
"value": 8
|
||||
"value": 8,
|
||||
"min": 1,
|
||||
"max": 256, // arbitrary - significantly larger than word size for any known machine ("640k ought to be enough for anybody")
|
||||
"integer": true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@ -56,7 +56,8 @@ class UnescapeUnicodeCharacters extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const prefix = prefixToRegex[args[0]],
|
||||
regex = new RegExp(prefix+"([a-f\\d]{4})", "ig");
|
||||
quantifier = args[0] === "U+" ? "{4,6}" : "{4}",
|
||||
regex = new RegExp(prefix+"([a-f\\d]"+quantifier+")", "ig");
|
||||
let output = "",
|
||||
m,
|
||||
i = 0;
|
||||
|
||||
@ -31,7 +31,10 @@ class XORBruteForce extends Operation {
|
||||
{
|
||||
"name": "Key length",
|
||||
"type": "number",
|
||||
"value": 1
|
||||
"value": 1,
|
||||
"min": 1,
|
||||
"max": 2,
|
||||
"integer": true
|
||||
},
|
||||
{
|
||||
"name": "Sample length",
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
import Operation from "../Operation.mjs";
|
||||
import Utils from "../Utils.mjs";
|
||||
import { toHex } from "../lib/Hex.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* XOR Checksum operation
|
||||
@ -43,7 +43,7 @@ class XORChecksum extends Operation {
|
||||
run(input, args) {
|
||||
const blocksize = args[0];
|
||||
|
||||
|
||||
|
||||
if (!Number.isInteger(blocksize) || blocksize <= 0) {
|
||||
throw new OperationError("Blocksize must be a positive integer.");
|
||||
}
|
||||
|
||||
@ -218,6 +218,7 @@ module.exports = {
|
||||
testOpHtml(browser, "JSON Beautify", "{a:1}", ".json-dict .json-literal", "1");
|
||||
// testOp(browser, "JSON Minify", "test input", "test_output");
|
||||
// testOp(browser, "JSON to CSV", "test input", "test_output");
|
||||
testOp(browser, "Jsonata Query", '{"a": "SGVsbG8gV29ybGQh"}', '"Hello World!"', ["$base64decode($.a)"]);
|
||||
// testOp(browser, "JWT Decode", "test input", "test_output");
|
||||
// testOp(browser, "JWT Sign", "test input", "test_output");
|
||||
// testOp(browser, "JWT Verify", "test input", "test_output");
|
||||
@ -345,8 +346,8 @@ module.exports = {
|
||||
// testOp(browser, "Strip HTTP headers", "test input", "test_output");
|
||||
// testOp(browser, "Subsection", "test input", "test_output");
|
||||
// testOp(browser, "Substitute", "test input", "test_output");
|
||||
// testOp(browser, "Subtract", "test input", "test_output");
|
||||
// testOp(browser, "Sum", "test input", "test_output");
|
||||
testOp(browser, "Subtract", "321,123,test", "198", ["Comma"]);
|
||||
testOp(browser, "Sum", "321,123,test", "444", ["Comma"]);
|
||||
// testOp(browser, "Swap endianness", "test input", "test_output");
|
||||
// testOp(browser, "Symmetric Difference", "test input", "test_output");
|
||||
testOpHtml(browser, "Syntax highlighter", "var a = [4,5,6]", ".hljs-selector-attr", "[4,5,6]");
|
||||
|
||||
@ -9,4 +9,23 @@ TestRegister.addApiTests([
|
||||
assert(dish.presentAs);
|
||||
}),
|
||||
|
||||
it("Disk - should not error on serialized BigNumber (0)", () => {
|
||||
const dish = new Dish({ s: 1, e: 0, c: [0] }, Dish.BIG_NUMBER);
|
||||
assert.strictEqual(dish.value.toString(), "0");
|
||||
}),
|
||||
|
||||
it("Dish - should not error on serialized BigNumber (1)", () => {
|
||||
const dish = new Dish({ c: [1], e: 0, s: 1 }, Dish.BIG_NUMBER);
|
||||
assert.strictEqual(dish.value.toString(), "1");
|
||||
}),
|
||||
|
||||
it("Dish - should not error on serialized BigNumber (-100)", () => {
|
||||
const dish = new Dish({ s: -1, e: 2, c: [100] }, Dish.BIG_NUMBER);
|
||||
assert.strictEqual(dish.value.toString(), "-100");
|
||||
}),
|
||||
|
||||
it("Dish - should not error on serialized BigNumber (NaN)", () => {
|
||||
const dish = new Dish({ s: null, e: null, c: null }, Dish.BIG_NUMBER);
|
||||
assert.strictEqual(dish.value.toString(), "NaN");
|
||||
}),
|
||||
]);
|
||||
|
||||
33
tests/operations/tests/Arithmetic.mjs
Normal file
33
tests/operations/tests/Arithmetic.mjs
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Tests for arithmetical operations
|
||||
*
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Subtract",
|
||||
input: "321,123,test",
|
||||
expectedOutput: "198",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Subtract",
|
||||
"args": ["Comma"]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Subtract - no valid input",
|
||||
input: "test",
|
||||
expectedOutput: "NaN",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Subtract",
|
||||
"args": ["Comma"]
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
@ -69,5 +69,43 @@ TestRegister.addTests([
|
||||
{ "op": "BLAKE3",
|
||||
"args": [16390, "ThiskeyisexactlythirtytwoBytesLo"] }
|
||||
]
|
||||
}
|
||||
},
|
||||
// test vectors from https://github.com/BLAKE3-team/BLAKE3/blob/master/test_vectors/test_vectors.json
|
||||
{
|
||||
name: "BLAKE3: Std test vector - 0 bytes input, plain hash",
|
||||
input: "",
|
||||
expectedOutput: "af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262e00f03e7b69af26b7faaf09fcd333050338ddfe085b8cc869ca98b206c08243a26f5487789e8f660afe6c99ef9e0c52b92e7393024a80459cf91f476f9ffdbda7001c22e159b402631f277ca96f2defdf1078282314e763699a31c5363165421cce14d",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "BLAKE3",
|
||||
"args": [131, ""]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "BLAKE3: Std test vector - 0 bytes input, keyed hash",
|
||||
input: "",
|
||||
expectedOutput: "92b2b75604ed3c761f9d6f62392c8a9227ad0ea3f09573e783f1498a4ed60d26b18171a2f22a4b94822c701f107153dba24918c4bae4d2945c20ece13387627d3b73cbf97b797d5e59948c7ef788f54372df45e45e4293c7dc18c1d41144a9758be58960856be1eabbe22c2653190de560ca3b2ac4aa692a9210694254c371e851bc8f",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "BLAKE3",
|
||||
"args": [131, "whats the Elvish word for friend"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "BLAKE3: Std test vector - 7 bytes input, keyed hash",
|
||||
input: "0001020304050607",
|
||||
expectedOutput: "be2f5495c61cba1bb348a34948c004045e3bd4dae8f0fe82bf44d0da245a060048eb5e68ce6dea1eb0229e144f578b3aa7e9f4f85febd135df8525e6fe40c6f0340d13dd09b255ccd5112a94238f2be3c0b5b7ecde06580426a93e0708555a265305abf86d874e34b4995b788e37a823491f25127a502fe0704baa6bfdf04e76c13276",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
args: [],
|
||||
},
|
||||
{
|
||||
"op": "BLAKE3",
|
||||
"args": [131, "whats the Elvish word for friend"]
|
||||
}
|
||||
]
|
||||
},
|
||||
]);
|
||||
|
||||
66
tests/operations/tests/DechunkHTTPResponse.mjs
Normal file
66
tests/operations/tests/DechunkHTTPResponse.mjs
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* DechunkHTTPResponse operation tests.
|
||||
*
|
||||
* @author Willi Ballenthin
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Dechunk HTTP response: CRLF line endings",
|
||||
input: "7\r\nMozilla\r\n9\r\nDeveloper\r\n7\r\nNetwork\r\n0\r\n\r\n",
|
||||
expectedOutput: "MozillaDeveloperNetwork",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Dechunk HTTP response",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Dechunk HTTP response: LF line endings",
|
||||
input: "7\nMozilla\n9\nDeveloper\n7\nNetwork\n0\n\n",
|
||||
expectedOutput: "MozillaDeveloperNetwork",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Dechunk HTTP response",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Dechunk HTTP response: single chunk",
|
||||
input: "5\r\nHello\r\n0\r\n\r\n",
|
||||
expectedOutput: "Hello",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Dechunk HTTP response",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Dechunk HTTP response: trailing headers discarded",
|
||||
input: "7\nMozilla\n9\nDeveloper\n7\nNetwork\n0\nExpires: Wed, 21 Oct 2015 07:28:00 GMT\n",
|
||||
expectedOutput: "MozillaDeveloperNetwork",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Dechunk HTTP response",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Dechunk HTTP response: hex chunk sizes",
|
||||
input: "a\r\n0123456789\r\n0\r\n\r\n",
|
||||
expectedOutput: "0123456789",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Dechunk HTTP response",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
66
tests/operations/tests/FromBase.mjs
Normal file
66
tests/operations/tests/FromBase.mjs
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* From Base operation tests.
|
||||
*
|
||||
* @author Willi Ballenthin
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "From Base: binary integer",
|
||||
input: "1010",
|
||||
expectedOutput: "10",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base",
|
||||
args: [2],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base: binary fraction",
|
||||
input: "10.1",
|
||||
expectedOutput: "2.5",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base",
|
||||
args: [2],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base: hex fraction",
|
||||
input: "a.8",
|
||||
expectedOutput: "10.5",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base",
|
||||
args: [16],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base: octal integer",
|
||||
input: "77",
|
||||
expectedOutput: "63",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base",
|
||||
args: [8],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base: octal fraction",
|
||||
input: "7.4",
|
||||
expectedOutput: "7.5",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base",
|
||||
args: [8],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
@ -86,4 +86,64 @@ TestRegister.addTests([
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gzip: Comment with checksum round-trips through Gunzip",
|
||||
input: "hello hello hello",
|
||||
expectedOutput: "hello hello hello",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "", "test", true]
|
||||
},
|
||||
{
|
||||
op: "Gunzip",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gzip: Filename and comment with checksum round-trips through Gunzip",
|
||||
input: "The quick brown fox jumped over the slow dog",
|
||||
expectedOutput: "The quick brown fox jumped over the slow dog",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "file.txt", "a comment", true]
|
||||
},
|
||||
{
|
||||
op: "Gunzip",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gzip: No comment, with checksum round-trips through Gunzip",
|
||||
input: "The quick brown fox jumped over the slow dog",
|
||||
expectedOutput: "The quick brown fox jumped over the slow dog",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "", "", true]
|
||||
},
|
||||
{
|
||||
op: "Gunzip",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gzip: No options round-trips through Gunzip",
|
||||
input: "The quick brown fox jumped over the slow dog",
|
||||
expectedOutput: "The quick brown fox jumped over the slow dog",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "", "", false]
|
||||
},
|
||||
{
|
||||
op: "Gunzip",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
]);
|
||||
|
||||
@ -45,6 +45,17 @@ TestRegister.addTests([
|
||||
{ op: "Render Image", args: ["Base64"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Generate Image: empty mode",
|
||||
input: "",
|
||||
expectedOutput: "Unsupported Mode: ()",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Generate Image",
|
||||
args: ["", 8, 64]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Extract EXIF: nothing",
|
||||
input: "",
|
||||
|
||||
@ -548,4 +548,27 @@ TestRegister.addTests([
|
||||
},
|
||||
],
|
||||
},
|
||||
// Base64 functions (issue #2063)
|
||||
{
|
||||
name: "Jsonata: $base64decode",
|
||||
input: "{}",
|
||||
expectedOutput: '"Hello World!"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ['$base64decode("SGVsbG8gV29ybGQh")'],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Jsonata: $base64encode",
|
||||
input: "{}",
|
||||
expectedOutput: '"SGVsbG8gV29ybGQh"',
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Jsonata Query",
|
||||
args: ['$base64encode("Hello World!")'],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
@ -75,6 +75,39 @@ TestRegister.addTests([
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "UTF-8 Base64 non-ASCII",
|
||||
input: "Subject: =?UTF-8?B?Y2Fmw6k=?=",
|
||||
expectedOutput: "Subject: café",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "MIME Decoding",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "UTF-8 Base64 multibyte CJK",
|
||||
input: "Subject: =?UTF-8?B?5pel5pys6Kqe?=",
|
||||
expectedOutput: "Subject: 日本語",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "MIME Decoding",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "UTF-8 Base64 ASCII-only",
|
||||
input: "Subject: =?UTF-8?B?aGVsbG8=?=",
|
||||
expectedOutput: "Subject: hello",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "MIME Decoding",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ISO Decoding",
|
||||
input: "From: =?US-ASCII?Q?Keith_Moore?= <moore@cs.utk.edu>\nTo: =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?= <keld@dkuug.dk>\nCC: =?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>\nSubject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\n=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=",
|
||||
|
||||
33
tests/operations/tests/Median.mjs
Normal file
33
tests/operations/tests/Median.mjs
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Median operation tests.
|
||||
*
|
||||
* @author copilot-swe-agent[bot]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Median: odd-length input",
|
||||
input: "10 1 2",
|
||||
expectedOutput: "2",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Median",
|
||||
args: ["Space"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Median: even-length input",
|
||||
input: "10 1 2 5",
|
||||
expectedOutput: "3.5",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Median",
|
||||
args: ["Space"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
@ -52,5 +52,46 @@ TestRegister.addTests([
|
||||
"args": [1, 4, true] // length value is patently wrong, should be ignored by BER.
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Parse TLV: BER long-form length (two-byte length encoding)",
|
||||
input: "\x01\x82\x01\x00" + "A".repeat(256) + "\x02\x03\x41\x42\x43",
|
||||
expectedOutput: JSON.stringify([
|
||||
{"key": [1], "length": 256, "value": Array(256).fill(65)},
|
||||
{"key": [2], "length": 3, "value": [65, 66, 67]}
|
||||
], null, 4),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Parse TLV",
|
||||
"args": [1, 1, true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Parse TLV: BER long-form length (one-byte length encoding)",
|
||||
input: "\x01\x81\x80" + "B".repeat(128),
|
||||
expectedOutput: JSON.stringify([
|
||||
{"key": [1], "length": 128, "value": Array(128).fill(66)}
|
||||
], null, 4),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Parse TLV",
|
||||
"args": [1, 1, true]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Parse TLV: BER multiple entries with mixed short and long-form lengths",
|
||||
input: "\x01\x05\x48\x65\x6c\x6c\x6f\x02\x81\x05\x57\x6f\x72\x6c\x64",
|
||||
expectedOutput: JSON.stringify([
|
||||
{"key": [1], "length": 5, "value": [72, 101, 108, 108, 111]},
|
||||
{"key": [2], "length": 5, "value": [87, 111, 114, 108, 100]}
|
||||
], null, 4),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Parse TLV",
|
||||
"args": [1, 1, true]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
|
||||
const oversizedPdfLikeInput = "%PDF-1.0\n" + "A".repeat(5000);
|
||||
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "RenderPDF",
|
||||
@ -34,4 +37,19 @@ TestRegister.addTests([
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "RenderPDF followed by Generate QR Code error returns plain text",
|
||||
input: oversizedPdfLikeInput,
|
||||
expectedOutput: "Error generating QR code. (Error: Too much data)",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Render PDF",
|
||||
"args": ["Raw"]
|
||||
},
|
||||
{
|
||||
"op": "Generate QR Code",
|
||||
"args": ["PNG", 1, 0, "High"]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
@ -53,4 +53,26 @@ TestRegister.addTests([
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Set Difference: duplicates in first set are removed",
|
||||
input: "red,red,blue\n\nblue",
|
||||
expectedOutput: "red",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Set Difference",
|
||||
args: ["\n\n", ","],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Set Difference: duplicates in both sets",
|
||||
input: "1 1 2 2 3\n\n2 2 3 3",
|
||||
expectedOutput: "1",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Set Difference",
|
||||
args: ["\n\n", " "],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
@ -52,5 +52,27 @@ TestRegister.addTests([
|
||||
args: ["z", "-"],
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Set Intersection: duplicates in first set are removed",
|
||||
input: "red,red,blue\n\nred,blue",
|
||||
expectedOutput: "red,blue",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Set Intersection",
|
||||
args: ["\n\n", ","],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Set Intersection: duplicates in both sets",
|
||||
input: "1 1 2 2 3\n\n2 2 3 3 4",
|
||||
expectedOutput: "2 3",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Set Intersection",
|
||||
args: ["\n\n", " "],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
39
tests/operations/tests/ShowOnMap.mjs
Normal file
39
tests/operations/tests/ShowOnMap.mjs
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Show on map tests
|
||||
*
|
||||
* @author Leon Zandman [leon@wirwar.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2026
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Show on map: valid coordinate pair",
|
||||
input: "51.5007, -0.1246",
|
||||
// The presented output is the Leaflet map HTML; just check the coordinates made it through.
|
||||
expectedMatch: /51\.5007,-0\.1246/,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Show on map",
|
||||
args: [13, "Auto", "Auto"]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// Regression test: a comma-separated input with the delimiter set to "\n" used to be
|
||||
// mis-detected as a single Degrees Decimal Minutes value (1° 24' = 1.4°), producing a single
|
||||
// coordinate. That single value was then passed to Leaflet's setView([1.4], ...), throwing
|
||||
// an uncaught "Cannot read properties of null (reading 'lat')" TypeError in the browser.
|
||||
name: "Show on map: single value is rejected with a helpful error",
|
||||
input: "1, 24",
|
||||
expectedOutput: "Could not show coordinates '1.4' on the map. Expected a latitude and longitude pair - check that the input format and delimiter are correct.",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Show on map",
|
||||
args: [13, "Auto", "\\n"]
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
88
tests/operations/tests/UnescapeUnicodeCharacters.mjs
Normal file
88
tests/operations/tests/UnescapeUnicodeCharacters.mjs
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Unescape Unicode Characters operation tests.
|
||||
*
|
||||
* @author williballenthin
|
||||
* @copyright Crown Copyright 2024
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Unescape Unicode Characters: \\u 4-digit BMP",
|
||||
input: "\\u03c3\\u03bf\\u03c5",
|
||||
expectedOutput: "σου",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape Unicode Characters",
|
||||
args: ["\\u"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Unescape Unicode Characters: %u 4-digit BMP",
|
||||
input: "%u03c3%u03bf%u03c5",
|
||||
expectedOutput: "σου",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape Unicode Characters",
|
||||
args: ["%u"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Unescape Unicode Characters: U+ 4-digit BMP",
|
||||
input: "U+0041",
|
||||
expectedOutput: "A",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape Unicode Characters",
|
||||
args: ["U+"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Unescape Unicode Characters: U+ 5-digit astral plane emoji",
|
||||
input: "U+1F600",
|
||||
expectedOutput: "\u{1F600}",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape Unicode Characters",
|
||||
args: ["U+"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Unescape Unicode Characters: U+ 6-digit zero-padded",
|
||||
input: "U+000041",
|
||||
expectedOutput: "A",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape Unicode Characters",
|
||||
args: ["U+"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Unescape Unicode Characters: U+ mixed lengths",
|
||||
input: "U+0041 U+1F600 U+000042",
|
||||
expectedOutput: "A \u{1F600} B",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape Unicode Characters",
|
||||
args: ["U+"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Unescape Unicode Characters: passthrough with no matches",
|
||||
input: "hello world",
|
||||
expectedOutput: "hello world",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Unescape Unicode Characters",
|
||||
args: ["\\u"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
@ -88,8 +88,8 @@ module.exports = {
|
||||
from: "tesseract/**/*",
|
||||
to: "assets/"
|
||||
}, {
|
||||
context: "node_modules/tesseract.js/",
|
||||
from: "dist/worker.min.js",
|
||||
context: "node_modules/tesseract.js/dist",
|
||||
from: "worker.min.js",
|
||||
to: "assets/tesseract"
|
||||
}, {
|
||||
context: "node_modules/tesseract.js-core/",
|
||||
@ -221,7 +221,7 @@ module.exports = {
|
||||
},
|
||||
{ // Third party images are inlined
|
||||
test: /\.(png|jpg|gif)$/,
|
||||
exclude: /web\/static/,
|
||||
include: /node_modules/,
|
||||
type: "asset/inline",
|
||||
},
|
||||
]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user