diff --git a/.github/workflows/release-current-version.yml b/.github/workflows/release-current-version.yml
index 6d6faae..641a3b7 100644
--- a/.github/workflows/release-current-version.yml
+++ b/.github/workflows/release-current-version.yml
@@ -2,10 +2,8 @@ name: Release Current Version
on:
push:
- branches: [ master, main ]
+ branches: [ master, main, support/v1 ]
jobs:
Run:
- uses: polarityio/polarity-github-actions/.github/workflows/release-server-versions-for-int-store.yml@master
- # with:
- # use-integration-development-checklist: false
+ uses: polarityio/polarity-github-actions/.github/workflows/release-integration.yml@master
diff --git a/.github/workflows/run-int-dev-checklist.yml b/.github/workflows/run-int-dev-checklist.yml
index ffa86d7..12eba68 100644
--- a/.github/workflows/run-int-dev-checklist.yml
+++ b/.github/workflows/run-int-dev-checklist.yml
@@ -2,22 +2,23 @@ name: Run Integration Development Checklist
on:
pull_request:
- branches: [ master, main, develop ]
+ branches: [ master, main, develop, support/v1 ]
jobs:
run-integration-development-checklist:
runs-on: ubuntu-latest
- container: 'centos:7'
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-node@v1
- - name: Test NPM Install
- id: test-npm-install
- run: |
- npm ci
- - name: Polarity Integration Development Checklist
- id: int-dev-checklist
- uses: polarityio/polarity-integration-development-checklist@main
- with:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - uses: actions/checkout@v6
+ - uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+ - name: Test NPM Install
+ id: test-npm-install
+ run: |
+ npm ci
+ - name: Polarity Integration Development Checklist
+ id: int-dev-checklist
+ uses: polarityio/polarity-integration-development-checklist@main
+ with:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index f7fe565..6b8cdd1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,4 +33,5 @@ test-runner.js
.polarity.conf
-data/
\ No newline at end of file
+data/
+dist/
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..521a9f7
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+legacy-peer-deps=true
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..55a10aa
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,4 @@
+dist/
+node_modules/
+mocks/
+package-lock.json
diff --git a/.prettierrc b/.prettierrc
index 8dff95d..e98ecea 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,11 +1,11 @@
-{
- "arrowParens": "always",
- "bracketSpacing": true,
- "printWidth": 90,
- "proseWrap": "preserve",
- "semi": true,
- "singleQuote": true,
- "tabWidth": 2,
- "trailingComma": "none",
- "useTabs": false
-}
\ No newline at end of file
+{
+ "arrowParens": "always",
+ "bracketSpacing": true,
+ "printWidth": 100,
+ "proseWrap": "preserve",
+ "semi": true,
+ "singleQuote": true,
+ "tabWidth": 2,
+ "trailingComma": "none",
+ "useTabs": false
+}
diff --git a/LICENSE b/LICENSE
index 6af51a9..5ed68de 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1 @@
-MIT License
-
-Copyright (c) 2022 Polarity.io, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
+Copyright 2026 Dataminr, Inc. All rights reserved.
diff --git a/README.md b/README.md
index e257c9b..4fed2df 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@
* List of all detections associated with Host
-
+
## About Qualys
@@ -42,4 +42,4 @@ Installation instructions for integrations are provided on the [PolarityIO GitHu
## Polarity
Polarity is a memory-augmentation platform that improves and accelerates analyst decision making. For more information about the Polarity platform please see:
-https://polarity.io/
\ No newline at end of file
+https://polarity.io/
diff --git a/components/block.js b/components/block.js
deleted file mode 100644
index fd19836..0000000
--- a/components/block.js
+++ /dev/null
@@ -1,74 +0,0 @@
-polarity.export = PolarityComponent.extend({
- details: Ember.computed.alias('block.data.details'),
- summary: Ember.computed.alias('block.data.summary'),
- tabKeys: Ember.computed.alias('details.tabKeys'),
- timezone: Ember.computed('Intl', function () {
- return Intl.DateTimeFormat().resolvedOptions().timeZone;
- }),
- expandableTitleStates: {},
- copiedStates: {},
- isRunningStates: {},
- messageStates: {},
- errorMessageStates: {},
- hostDetectionsFound: false,
- activeTab: '',
- init() {
- const details = this.get('details');
- this.set(
- 'activeTab',
- this.get('tabKeys').find((tabKey) => details[tabKey] && details[tabKey].length)
- );
-
- this._super(...arguments);
- },
- actions: {
- changeTab: function (tabName) {
- this.set('activeTab', tabName);
- },
- toggleExpandableTitle: function (
- displayFieldIndex,
- itemDisplayFieldsIndex,
- fieldName
- ) {
- const modifiedExpandableTitleStates = Object.assign(
- {},
- this.get('expandableTitleStates'),
- {
- [`${displayFieldIndex}${itemDisplayFieldsIndex}${fieldName}`]: !this.get(
- 'expandableTitleStates'
- )[`${displayFieldIndex}${itemDisplayFieldsIndex}${fieldName}`]
- }
- );
-
- this.set(`expandableTitleStates`, modifiedExpandableTitleStates);
- },
- copyField: function (
- displayFieldValue,
- displayFieldIndex,
- displayFieldLabel,
- subIndex,
- shouldCopyFieldLabel
- ) {
- navigator.clipboard.writeText(
- `${shouldCopyFieldLabel ? `${displayFieldLabel}: ` : ''}${displayFieldValue}`
- );
-
- this.set(
- `copiedStates`,
- Object.assign({}, this.get('copiedStates'), {
- [`${displayFieldIndex}${displayFieldLabel}${subIndex}`]: true
- })
- );
- this.get('block').notifyPropertyChange('data');
- setTimeout(() => {
- this.set(
- `copiedStates`,
- Object.assign({}, this.get('copiedStates'), {
- [`${displayFieldIndex}${displayFieldLabel}${subIndex}`]: false
- })
- );
- this.get('block').notifyPropertyChange('data');
- }, 3000);
- }
- }
-});
diff --git a/config/config.js b/config/config.js
deleted file mode 100644
index c13ad36..0000000
--- a/config/config.js
+++ /dev/null
@@ -1,65 +0,0 @@
-module.exports = {
- name: 'Qualys',
- acronym: 'QLS',
- description:
- "The Polarity Qualys Integration queries the Qualys Cloud Platform's Host Detection List and KnowledgeBase for IP Addresses, Domains, CVEs and QIDs.",
- entityTypes: ['IPv4', 'IPv6'],
- customTypes: [
- {
- key: 'qid',
- regex: /(?:QID|qid):\s*\d{1,8}/
- }
- ],
- defaultColor: 'light-purple',
- styles: ['./styles/styles.less'],
- onDemandOnly: true,
- block: {
- component: {
- file: './components/block.js'
- },
- template: {
- file: './templates/block.hbs'
- }
- },
- request: {
- cert: '',
- key: '',
- passphrase: '',
- ca: '',
- proxy: ""
- },
- logging: {
- level: 'info' //trace, debug, info, warn, error, fatal
- },
-
- options: [
- {
- key: 'url',
- name: 'Qualys URL',
- description:
- 'The URL of the Qualys you would like to connect to (including http:// or https://)',
- default: '',
- type: 'text',
- userCanEdit: false,
- adminOnly: true
- },
- {
- key: 'username',
- name: 'Qualys Username',
- description: 'The Username for your Qualys Account',
- default: '',
- type: 'text',
- userCanEdit: false,
- adminOnly: true
- },
- {
- key: 'password',
- name: 'Qualys Password',
- description: 'The Password associated with the Qualys Account',
- default: '',
- type: 'password',
- userCanEdit: false,
- adminOnly: true
- }
- ]
-};
diff --git a/config/config.json b/config/config.json
index 8806fd1..8bf731e 100644
--- a/config/config.json
+++ b/config/config.json
@@ -3,39 +3,31 @@
"name": "Qualys",
"acronym": "QLS",
"description": "The Polarity Qualys Integration queries the Qualys Cloud Platform's Host Detection List and KnowledgeBase for IP Addresses, Domains, CVEs and QIDs.",
- "entityTypes": [
+ "runtimeVersion": 2,
+ "defaultColor": "light-purple",
+ "onDemandOnly": true,
+ "dataTypes": [
"IPv4",
"IPv6"
],
- "customTypes": [
- {
- "key": "qid",
- "regex": "(?:QID|qid):\\s*\\d{1,8}"
- }
- ],
- "defaultColor": "light-purple",
- "styles": [
- "./styles/styles.less"
- ],
- "onDemandOnly": true,
- "block": {
- "component": {
- "file": "./components/block.js"
- },
- "template": {
- "file": "./templates/block.hbs"
- }
- },
- "request": {
- "cert": "",
- "key": "",
- "passphrase": "",
- "ca": "",
- "proxy": ""
- },
"logging": {
"level": "info"
},
+ "webComponents": {
+ "id": "512a1044-4cd2-4184-b120-48de15680389",
+ "moduleFilename": "web-components.mjs",
+ "components": [
+ {
+ "type": "details",
+ "element": "px-int-4szfuj42ymklnvnabm9q4yt1l-qls-details-v3-4-0"
+ }
+ ]
+ },
+ "reducer": {
+ "details": {
+ "file": "./reducers/details.json"
+ }
+ },
"options": [
{
"key": "url",
@@ -63,11 +55,29 @@
"type": "password",
"userCanEdit": false,
"adminOnly": true
+ },
+ {
+ "key": "customTypeValueRegex",
+ "name": "Custom Type Value Regex",
+ "description": "A regular expression used to extract the numeric QID value from a matched Custom Type entity. The full regex match is used as the QID (no capture groups). Defaults to '\\d+$' which extracts trailing digits. Only applies when the Custom Type Data Type is enabled.",
+ "default": "\\d+$",
+ "type": "text",
+ "userCanEdit": false,
+ "adminOnly": true
}
],
- "reducer": {
- "details": {
- "file": "./reducers/details.json"
+ "customTypes": [
+ {
+ "key": "qid",
+ "regex": "(?:QID|qid)(?:\\s*:\\s*|\\s+)\\d{1,8}"
+ },
+ {
+ "key": "customType",
+ "name": "Custom Type",
+ "description": "A customer-defined entity type. Set the regex to match your organization's QID format in the Polarity admin Data Types settings. The integration will extract a numeric QID from each match using the 'Custom Type Value Regex' option.",
+ "regex": "CUSTOM-\\d+",
+ "editable": true,
+ "enabled": false
}
- }
+ ]
}
\ No newline at end of file
diff --git a/assets/Host List Detections.png b/docs/Host List Detections.png
similarity index 100%
rename from assets/Host List Detections.png
rename to docs/Host List Detections.png
diff --git a/assets/KnowledgeBase Record.png b/docs/KnowledgeBase Record.png
similarity index 100%
rename from assets/KnowledgeBase Record.png
rename to docs/KnowledgeBase Record.png
diff --git a/assets/hostDetectionsFullExample.png b/docs/hostDetectionsFullExample.png
similarity index 100%
rename from assets/hostDetectionsFullExample.png
rename to docs/hostDetectionsFullExample.png
diff --git a/assets/knowledgeBaseFullExample.png b/docs/knowledgeBaseFullExample.png
similarity index 100%
rename from assets/knowledgeBaseFullExample.png
rename to docs/knowledgeBaseFullExample.png
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..8040144
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,22 @@
+import eslint from '@eslint/js';
+import tseslint from 'typescript-eslint';
+import eslintConfigPrettier from 'eslint-config-prettier';
+
+export default tseslint.config(
+ eslint.configs.recommended,
+ ...tseslint.configs.recommended,
+ eslintConfigPrettier,
+ {
+ ignores: ['dist/', 'node_modules/', 'mocks/', 'vite.config.js']
+ },
+ {
+ files: ['src/**/*.ts', 'web-components/**/*.ts'],
+ rules: {
+ '@typescript-eslint/no-explicit-any': 'warn',
+ '@typescript-eslint/no-unused-vars': [
+ 'warn',
+ { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }
+ ]
+ }
+ }
+);
diff --git a/integration.js b/integration.js
deleted file mode 100644
index 275ab19..0000000
--- a/integration.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const createRequestWithDefaults = require('./src/createRequestWithDefaults');
-const { validateStringOptions, validateUrlOption } = require('./src/validateOptions');
-const { parseErrorToReadableJSON } = require('./src/dataTransformations');
-const { getLookupResults } = require('./src/getLookupResults');
-
-let Logger;
-let requestWithDefaults;
-
-const startup = async (logger) => {
- Logger = logger;
- requestWithDefaults = createRequestWithDefaults(Logger);
-};
-
-const doLookup = async (entities, options, cb) => {
- Logger.debug({ entities }, 'Entities');
-
- let lookupResults = [];
- try {
- lookupResults = await getLookupResults(
- entities,
- options,
- requestWithDefaults,
- Logger
- );
- } catch (error) {
- const err = parseErrorToReadableJSON(error);
- Logger.error({ error, formattedError: err }, 'Get Lookup Results Failed');
-
- return cb({
- detail: error.message ? error.message : 'Searching Failed',
- err
- });
- }
-
- Logger.trace({ lookupResults }, 'Lookup Results');
- cb(null, lookupResults);
-};
-
-const validateOptions = async (options, callback) => {
- const stringOptionsErrorMessages = {
- url: 'You must provide a valid Qualys URL.',
- username: 'You must provide a valid Qualys Username',
- password: 'You must provide a valid Qualys Password'
- };
-
- const stringValidationErrors = validateStringOptions(
- stringOptionsErrorMessages,
- options
- );
-
- const urlValidationErrors = validateUrlOption(options.url.value);
-
- const errors = stringValidationErrors.concat(urlValidationErrors);
-
- callback(null, errors);
-};
-
-module.exports = {
- startup,
- validateOptions,
- doLookup
-};
diff --git a/package-lock.json b/package-lock.json
index c288ba4..f82fe96 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,343 +1,3929 @@
{
"name": "qualys",
- "version": "3.2.1",
- "lockfileVersion": 1,
+ "version": "4.0.0",
+ "lockfileVersion": 3,
"requires": true,
- "dependencies": {
- "@postman/form-data": {
+ "packages": {
+ "": {
+ "name": "qualys",
+ "version": "4.0.0",
+ "license": "UNLICENSED",
+ "dependencies": {
+ "lodash": "^4.17.21",
+ "polarity-integration-utils": "^4.1.0",
+ "xml2js": "^0.6.2"
+ },
+ "devDependencies": {
+ "@eslint/js": "^10.0.1",
+ "@polarityio/integration-types": "^1.1.0",
+ "@polarityio/pi-components": "^1.9.3",
+ "@polarityio/vite-plugin-icl": "^1.0.1",
+ "@types/lodash": "^4.17.24",
+ "@types/xml2js": "^0.4.14",
+ "@vitest/browser": "^4.1.4",
+ "@vitest/browser-playwright": "^4.1.4",
+ "eslint": "^10.2.0",
+ "eslint-config-prettier": "^10.1.8",
+ "lit": "^3.3.2",
+ "playwright": "^1.59.1",
+ "prettier": "^3.8.3",
+ "typescript": "^5.9.3",
+ "typescript-eslint": "^8.58.2",
+ "vite": "^7.3.2",
+ "vitest": "^4.1.4"
+ }
+ },
+ "node_modules/@blazediff/core": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/@blazediff/core/-/core-1.9.1.tgz",
+ "integrity": "sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
+ "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
+ "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
+ "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
+ "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
+ "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
+ "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
+ "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
+ "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
+ "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
+ "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
+ "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
+ "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
+ "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
+ "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
+ "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
+ "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
+ "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
+ "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
+ "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
+ "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
+ "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.23.5",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz",
+ "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^3.0.5",
+ "debug": "^4.3.1",
+ "minimatch": "^10.2.4"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.5.tgz",
+ "integrity": "sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^1.2.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz",
+ "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz",
+ "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "eslint": "^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz",
+ "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz",
+ "integrity": "sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^1.2.1",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
+ "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
+ "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.5",
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
+ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@fortawesome/fontawesome-common-types": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.2.0.tgz",
+ "integrity": "sha512-IpR0bER9FY25p+e7BmFH25MZKEwFHTfRAfhOyJubgiDnoJNsSvJ7nigLraHtp4VOG/cy8D7uiV0dLkHOne5Fhw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/fontawesome-svg-core": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.2.0.tgz",
+ "integrity": "sha512-6639htZMjEkwskf3J+e6/iar+4cTNM9qhoWuRfj9F3eJD6r7iCzV1SWnQr2Mdv0QT0suuqU8BoJCZUyCtP9R4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "7.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@fortawesome/free-solid-svg-icons": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-7.2.0.tgz",
+ "integrity": "sha512-YTVITFGN0/24PxzXrwqCgnyd7njDuzp5ZvaCx5nq/jg55kUYd94Nj8UTchBdBofi/L0nwRfjGOg0E41d2u9T1w==",
+ "dev": true,
+ "license": "(CC-BY-4.0 AND MIT)",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "7.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
+ "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/types": "^0.15.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.8",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz",
+ "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.2",
+ "@humanfs/types": "^0.15.0",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/types": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz",
+ "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@lit-labs/ssr-dom-shim": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.5.1.tgz",
+ "integrity": "sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@lit/reactive-element": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.2.tgz",
+ "integrity": "sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.5.0"
+ }
+ },
+ "node_modules/@polarityio/integration-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@polarityio/integration-types/-/integration-types-1.1.0.tgz",
+ "integrity": "sha512-AEsWN3N5z92Ld8kuLC9sQUJFshlN76vjWYvQS1xoUFsybx55vErPYGOrZl8FZnUkUuxr+phIpv0vp5XtCJ7Gzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@polarityio/pi-button": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-button/-/pi-button-1.0.4.tgz",
+ "integrity": "sha512-l6kPPQTXDw5pRQ3xQ5CIz4AKiwrvSrXmKYCXP/nR4rYagQJDs/vykzcPRfoeZi7loRclagzqNi3WWh23Np2tzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-shared": "1.0.3",
+ "@polarityio/pi-tooltip": "1.0.4"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-button/node_modules/@polarityio/pi-shared": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.0.3.tgz",
+ "integrity": "sha512-emX5IT4sn1fNJBqABSDeXF+jv/RhTr8b+27jSTnnJ4Jas/APi4rWnZ203dqBI99PhYTV8cvePLabI5KOuKFg/g==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-button/node_modules/@polarityio/pi-tooltip": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-tooltip/-/pi-tooltip-1.0.4.tgz",
+ "integrity": "sha512-/q2b3wobIcmmE+EWzZAH995fmbsRZ7k3Usp/k0xadDXO/dU7kwgKdwat+P1rJ4ZNtvV/I9i9mDPsdimuQO6Tow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.6",
+ "@polarityio/pi-shared": "1.0.3"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-card": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-card/-/pi-card-1.2.3.tgz",
+ "integrity": "sha512-wsuUPNxqvQYSozt1XJ8j9I+Fiu9XfVNEaBSafSLyMn5BISdP9XGWkPomi9GqkzpMMBdXaWPk0q+GjYHEGFu5Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-icon": "1.0.3",
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-checkbox": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-checkbox/-/pi-checkbox-1.0.4.tgz",
+ "integrity": "sha512-QhuEoVNOHVG/zSRjG7s6iFNfcYhFqsbhFYSvnv9DD4DO1AmhZ83dmvxLkokKS+399jT/Nv5d2cYr9rmRsHj3rw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.2.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-checkbox/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-components": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-components/-/pi-components-1.9.3.tgz",
+ "integrity": "sha512-srGOiNZ7Ql+unJok+pZH2UExhrVg73941ospcFiHvsrCcLuM0tvCDW9LJ1QT+TfZwBaOSnEbEKbSoIeuPm7VOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-button": "1.0.4",
+ "@polarityio/pi-card": "1.2.3",
+ "@polarityio/pi-checkbox": "1.0.4",
+ "@polarityio/pi-copy-button": "1.1.0",
+ "@polarityio/pi-error": "1.1.3",
+ "@polarityio/pi-external-link": "1.0.4",
+ "@polarityio/pi-icon": "1.0.3",
+ "@polarityio/pi-input": "1.0.5",
+ "@polarityio/pi-key-value": "1.2.3",
+ "@polarityio/pi-object-table": "1.0.5",
+ "@polarityio/pi-radio": "1.0.4",
+ "@polarityio/pi-retry-button": "1.0.1",
+ "@polarityio/pi-scroller": "1.0.2",
+ "@polarityio/pi-section-header": "1.0.5",
+ "@polarityio/pi-select": "1.0.4",
+ "@polarityio/pi-shared": "1.3.1",
+ "@polarityio/pi-show-more": "1.1.3",
+ "@polarityio/pi-spinner": "1.0.4",
+ "@polarityio/pi-summary-tag": "1.1.0",
+ "@polarityio/pi-tab": "1.2.2",
+ "@polarityio/pi-tag": "1.0.6",
+ "@polarityio/pi-tooltip": "1.0.5"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-copy-button": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-copy-button/-/pi-copy-button-1.1.0.tgz",
+ "integrity": "sha512-EmNUq1DnzrwBqhf9clzuY5cRr0wzuJj8ZWfYaoLrGWGlzhke52XVR3/sRShB4DzH8GkdpYgb7duLM5epyvvQMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.2.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-button": "1.0.4",
+ "@polarityio/pi-shared": "1.2.1",
+ "@polarityio/pi-tooltip": "1.0.5"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-copy-button/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-error": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-error/-/pi-error-1.1.3.tgz",
+ "integrity": "sha512-aB7lqiD15axYvGBtUyjhhMduSQG1Myxnb/4K940NfcBS7prfEJbVjXsfJDexGJe1iUGKh5cCfEHeQ2fiQyp/5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-button": "1.0.4",
+ "@polarityio/pi-copy-button": "1.1.0",
+ "@polarityio/pi-icon": "1.0.3",
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-external-link": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-external-link/-/pi-external-link-1.0.4.tgz",
+ "integrity": "sha512-uKlNFq5V0UVnJ5zXI5DqZFvVtjjRMFFa2xaYRRpnOjX5vASlrIEXw/WBc7XM5QmOfEJ4t9yAIveA6d5OGy7I7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-icon": "1.0.3",
+ "@polarityio/pi-shared": "1.2.1",
+ "@polarityio/pi-tooltip": "1.0.5"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-external-link/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-icon": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-icon/-/pi-icon-1.0.3.tgz",
+ "integrity": "sha512-NWQurGNSZvOST2lehdaqsc9T5X0mddMNlFPQOgI2YaZJVBwSAahq+j8sL5gUgnLiX/YH4hB/UxuWiWkuOuiPxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-shared": "1.0.3"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-icon/node_modules/@polarityio/pi-shared": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.0.3.tgz",
+ "integrity": "sha512-emX5IT4sn1fNJBqABSDeXF+jv/RhTr8b+27jSTnnJ4Jas/APi4rWnZ203dqBI99PhYTV8cvePLabI5KOuKFg/g==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-input": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-input/-/pi-input-1.0.5.tgz",
+ "integrity": "sha512-AzKNCwUFuYQz9wfngkIqAFuHUEZF4jWHRLFxCOmRig6I0zx/nI5SQUQorZZPmyDxAnue5ilL/WaWHhXbiAGi9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.2.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-input/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-key-value": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-key-value/-/pi-key-value-1.2.3.tgz",
+ "integrity": "sha512-IEIbYMfTKzXcVWDpPJznECfJc1c6kAG5IJeB2HTrrX7X82wQopXX6wzeWJVZ97EYWWbGwO0+wt+IyaHDXAIUIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-icon": "1.0.3",
+ "@polarityio/pi-shared": "1.2.1",
+ "@polarityio/pi-tooltip": "1.0.5",
+ "date-fns": "^4.0.0"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-key-value/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-object-table": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-object-table/-/pi-object-table-1.0.5.tgz",
+ "integrity": "sha512-NzYSXJL/SiGgAdn7SJJU2V/J8l2CbQEMu93pqywGF35MOnZ5bfWvLm4JkIHK7OjjCcFOo6vMLKMtSBrLfw7unw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-radio": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-radio/-/pi-radio-1.0.4.tgz",
+ "integrity": "sha512-qhw7s0hJVdwcBH83LnCR02r6mheriI6kCFxVrJHx97/MLSvF70M7gmbDEU3skfGogzHueQ/TUw+o0jWAJRyInA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.2.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-radio/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-retry-button": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-retry-button/-/pi-retry-button-1.0.1.tgz",
+ "integrity": "sha512-z8DnVCTlmiUyDSFo6jP72qTeZgLPcIPLwKxZTtNZBFYC+BuRP8hXe4GVWXd7kSyymoJze0oHMD8Zl0nAAExmcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-button": "1.0.4",
+ "@polarityio/pi-shared": "1.2.0",
+ "@polarityio/pi-spinner": "1.0.3",
+ "@polarityio/pi-tooltip": "1.0.4"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-retry-button/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.0.tgz",
+ "integrity": "sha512-esRx4+jP9jmKdmXk1ZSyOMbiJ/IxjL+FKUw3iwn3HmX3LaNCBfgIAap/81+tA8Ocgvyr2EjWa1j+FN7ikr+sMg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-retry-button/node_modules/@polarityio/pi-spinner": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-spinner/-/pi-spinner-1.0.3.tgz",
+ "integrity": "sha512-TLwb+zzoLiS5sb858RZgcWJXtgZ/AnQ/W5hncPrvuHJLwltGZlkOX+juyQPeqtucWD/p7PexDTKoxHfCOyfbiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.0.3"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-retry-button/node_modules/@polarityio/pi-spinner/node_modules/@polarityio/pi-shared": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.0.3.tgz",
+ "integrity": "sha512-emX5IT4sn1fNJBqABSDeXF+jv/RhTr8b+27jSTnnJ4Jas/APi4rWnZ203dqBI99PhYTV8cvePLabI5KOuKFg/g==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-retry-button/node_modules/@polarityio/pi-tooltip": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-tooltip/-/pi-tooltip-1.0.4.tgz",
+ "integrity": "sha512-/q2b3wobIcmmE+EWzZAH995fmbsRZ7k3Usp/k0xadDXO/dU7kwgKdwat+P1rJ4ZNtvV/I9i9mDPsdimuQO6Tow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.6",
+ "@polarityio/pi-shared": "1.0.3"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-retry-button/node_modules/@polarityio/pi-tooltip/node_modules/@polarityio/pi-shared": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.0.3.tgz",
+ "integrity": "sha512-emX5IT4sn1fNJBqABSDeXF+jv/RhTr8b+27jSTnnJ4Jas/APi4rWnZ203dqBI99PhYTV8cvePLabI5KOuKFg/g==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-scroller": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-scroller/-/pi-scroller-1.0.2.tgz",
+ "integrity": "sha512-d93nkdLxpiTcxMlaqO9VtqLiRsSor3JzYzIj7g8+5tiYWyR60q9TVHYiBrhSkgthp3MrfSqmbaYKtvraDR8HsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-section-header": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-section-header/-/pi-section-header-1.0.5.tgz",
+ "integrity": "sha512-pjYHqnISsEchARTfjC72G9WnTHN4mdxW0u6X3dRiX+1EC82G8zFuNc4XoLgxb015hEYSn5xZGlsKkKJ5EfohLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-select": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-select/-/pi-select-1.0.4.tgz",
+ "integrity": "sha512-Frl7QLWDgQqUs83LABiEiKzyFjEVtrBRLJjMD1CotC1KcNluIi3yChi1KRZhBLfZr+pa9K0iTQsX6/AGP7/+xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.6",
+ "@polarityio/pi-shared": "1.0.3"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-select/node_modules/@polarityio/pi-shared": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.0.3.tgz",
+ "integrity": "sha512-emX5IT4sn1fNJBqABSDeXF+jv/RhTr8b+27jSTnnJ4Jas/APi4rWnZ203dqBI99PhYTV8cvePLabI5KOuKFg/g==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-shared": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.3.1.tgz",
+ "integrity": "sha512-TXvKZBmFj9rqqZtSMImYLNVFtaYTCVJ69rPxrYBbOSOkoUvPWscCKP9zvT9xJHMaD7tjocI0gv7BvDc3H7grmg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-show-more": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-show-more/-/pi-show-more-1.1.3.tgz",
+ "integrity": "sha512-fZhwYRaw03tBEM3u+R/Y7wOcwnaq48ectu2GhE5ygpXNLx5dfyHg5huYKD9KX+JF6cUuOMPE4ogcGvGNaWcIWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-button": "1.0.4",
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-spinner": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-spinner/-/pi-spinner-1.0.4.tgz",
+ "integrity": "sha512-HsaWqOkzTMe6ZqaBZ3XBkv27BJ5dn5PJrgtOwShmVFQDDx0AY0Ijk8w2rVk6DaaYnBotCeTtw53gUZIR6X0Gow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.2.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-spinner/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-summary-tag": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-summary-tag/-/pi-summary-tag-1.1.0.tgz",
+ "integrity": "sha512-aR+AgZ9Vcro7u+TQYvM0qwhWxEXSGrkAXEmdZJaZPiAfVd8TXnwjWwZnyF/jF3ttuU0RPXXsgdhk6t8ijy3iKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-shared": "1.2.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-summary-tag/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-tab": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-tab/-/pi-tab-1.2.2.tgz",
+ "integrity": "sha512-tqLT0kXTPmz/e0HWw9S3ogQ5KvN+4NZX5AYY0oW3hI4qtMRTJi/nilHCpgqrrsPPJlYRCWO8UkvBLMgrzDRMcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-tag": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-tag/-/pi-tag-1.0.6.tgz",
+ "integrity": "sha512-H/Td6m/n1MOtafmskWgCDhdak2BsuTubpWYzS6OhvxcJcDTQ/b8g2bKG9F/6kFqQ0vYG0rG8mQzHm5E3pFVBrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^7.0.0",
+ "@fortawesome/free-solid-svg-icons": "^7.0.0",
+ "@polarityio/pi-icon": "1.0.3",
+ "@polarityio/pi-shared": "1.3.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-tooltip": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-tooltip/-/pi-tooltip-1.0.5.tgz",
+ "integrity": "sha512-Ii0Y+j4ji0LGPKBSHZAfdhD5gvrvs++8RStaY591nan9cLDzSC9H3v8PTtUE2pKXsoVyjAk5xmbpLP539VAGKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.6",
+ "@polarityio/pi-shared": "1.2.1"
+ },
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/pi-tooltip/node_modules/@polarityio/pi-shared": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/pi-shared/-/pi-shared-1.2.1.tgz",
+ "integrity": "sha512-kNemzBeJKcN7QFHdnf1j1L+ImRjIYtRxBDJrlZEvRVKybNlnZwGPjAGyOTRsyAeMJ16HiOECnY/cNMeknEC9/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "lit": "^3.0.0"
+ }
+ },
+ "node_modules/@polarityio/vite-plugin-icl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@polarityio/vite-plugin-icl/-/vite-plugin-icl-1.0.1.tgz",
+ "integrity": "sha512-jKYwWlhENNOj4aQYqMcvnT/txKN/UdLW8F+tudjHTpm83TYE24JnpUVn7y6KwJ5a2w38cuPloGooymFCQs5u/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=24"
+ },
+ "peerDependencies": {
+ "vite": ">=5"
+ }
+ },
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@postman/form-data": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz",
"integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==",
- "requires": {
+ "dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
- "@postman/tough-cookie": {
+ "node_modules/@postman/tough-cookie": {
"version": "4.1.3-postman.1",
"resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.3-postman.1.tgz",
"integrity": "sha512-txpgUqZOnWYnUHZpHjkfb0IwVH4qJmyq77pPnJLlfhMtdCLMFTEeQHlzQiK906aaNCe4NEB5fGJHo9uzGbFMeA==",
- "requires": {
+ "dependencies": {
"psl": "^1.1.33",
"punycode": "^2.1.1",
"universalify": "^0.2.0",
"url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
}
},
- "@postman/tunnel-agent": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz",
- "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==",
- "requires": {
+ "node_modules/@postman/tunnel-agent": {
+ "version": "0.6.8",
+ "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.8.tgz",
+ "integrity": "sha512-2U42SmZW5G+suEcS++zB94sBWNO4qD4bvETGFRFDTqSpYl5ksfjcPqzYpgQgXgUmb6dfz+fAGbkcRamounGm0w==",
+ "license": "Apache-2.0",
+ "dependencies": {
"safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz",
+ "integrity": "sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz",
+ "integrity": "sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz",
+ "integrity": "sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.3.tgz",
+ "integrity": "sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz",
+ "integrity": "sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz",
+ "integrity": "sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz",
+ "integrity": "sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz",
+ "integrity": "sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz",
+ "integrity": "sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz",
+ "integrity": "sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz",
+ "integrity": "sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz",
+ "integrity": "sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz",
+ "integrity": "sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz",
+ "integrity": "sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz",
+ "integrity": "sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz",
+ "integrity": "sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz",
+ "integrity": "sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz",
+ "integrity": "sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz",
+ "integrity": "sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz",
+ "integrity": "sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz",
+ "integrity": "sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz",
+ "integrity": "sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz",
+ "integrity": "sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz",
+ "integrity": "sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz",
+ "integrity": "sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@standard-schema/spec": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+ "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
+ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*",
+ "assertion-error": "^2.0.1"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/esrecurse": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz",
+ "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
+ "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/lodash": {
+ "version": "4.17.24",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz",
+ "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "25.7.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.7.0.tgz",
+ "integrity": "sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.21.0"
+ }
+ },
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/xml2js": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz",
+ "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.3.tgz",
+ "integrity": "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.12.2",
+ "@typescript-eslint/scope-manager": "8.59.3",
+ "@typescript-eslint/type-utils": "8.59.3",
+ "@typescript-eslint/utils": "8.59.3",
+ "@typescript-eslint/visitor-keys": "8.59.3",
+ "ignore": "^7.0.5",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.59.3",
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.3.tgz",
+ "integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.59.3",
+ "@typescript-eslint/types": "8.59.3",
+ "@typescript-eslint/typescript-estree": "8.59.3",
+ "@typescript-eslint/visitor-keys": "8.59.3",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.3.tgz",
+ "integrity": "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.59.3",
+ "@typescript-eslint/types": "^8.59.3",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.3.tgz",
+ "integrity": "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.59.3",
+ "@typescript-eslint/visitor-keys": "8.59.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.3.tgz",
+ "integrity": "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.3.tgz",
+ "integrity": "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.59.3",
+ "@typescript-eslint/typescript-estree": "8.59.3",
+ "@typescript-eslint/utils": "8.59.3",
+ "debug": "^4.4.3",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.3.tgz",
+ "integrity": "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.3.tgz",
+ "integrity": "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.59.3",
+ "@typescript-eslint/tsconfig-utils": "8.59.3",
+ "@typescript-eslint/types": "8.59.3",
+ "@typescript-eslint/visitor-keys": "8.59.3",
+ "debug": "^4.4.3",
+ "minimatch": "^10.2.2",
+ "semver": "^7.7.3",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.3.tgz",
+ "integrity": "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.1",
+ "@typescript-eslint/scope-manager": "8.59.3",
+ "@typescript-eslint/types": "8.59.3",
+ "@typescript-eslint/typescript-estree": "8.59.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.3.tgz",
+ "integrity": "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.59.3",
+ "eslint-visitor-keys": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@vitest/browser": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.6.tgz",
+ "integrity": "sha512-ynsspTubXGSpa58JFJ24xIQt4z4A25epSbugEyaTmmrV1//Wec9EgE/LtoaC6yxUrXi5P7erGHRrkdZIHaVQuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@blazediff/core": "1.9.1",
+ "@vitest/mocker": "4.1.6",
+ "@vitest/utils": "4.1.6",
+ "magic-string": "^0.30.21",
+ "pngjs": "^7.0.0",
+ "sirv": "^3.0.2",
+ "tinyrainbow": "^3.1.0",
+ "ws": "^8.19.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "vitest": "4.1.6"
+ }
+ },
+ "node_modules/@vitest/browser-playwright": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.6.tgz",
+ "integrity": "sha512-4csoeyl/qwHyxU2zNL0++WaoDr8YJDXOQPwWPNJoTZ+QzcdO3INYKgF5Zfz730Io7zbkuv914aZmfQ+QE+1Hvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/browser": "4.1.6",
+ "@vitest/mocker": "4.1.6",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "playwright": "*",
+ "vitest": "4.1.6"
+ },
+ "peerDependenciesMeta": {
+ "playwright": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.6.tgz",
+ "integrity": "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.1.0",
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "4.1.6",
+ "@vitest/utils": "4.1.6",
+ "chai": "^6.2.2",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.6.tgz",
+ "integrity": "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "4.1.6",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.21"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.6.tgz",
+ "integrity": "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.6.tgz",
+ "integrity": "sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "4.1.6",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.6.tgz",
+ "integrity": "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.1.6",
+ "@vitest/utils": "4.1.6",
+ "magic-string": "^0.30.21",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.6.tgz",
+ "integrity": "sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.6.tgz",
+ "integrity": "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "4.1.6",
+ "convert-source-map": "^2.0.0",
+ "tinyrainbow": "^3.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
}
},
- "ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "requires": {
+ "node_modules/ajv": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
+ "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "asn1": {
+ "node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
- "requires": {
+ "license": "MIT",
+ "dependencies": {
"safer-buffer": "~2.1.0"
}
},
- "assert-plus": {
+ "node_modules/assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="
+ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
},
- "asynckit": {
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
- "aws-sign2": {
+ "node_modules/aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA=="
+ "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+ "engines": {
+ "node": "*"
+ }
},
- "aws4": {
+ "node_modules/aws4": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
},
- "base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ "node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
},
- "bcrypt-pbkdf": {
+ "node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
- "requires": {
+ "license": "BSD-3-Clause",
+ "dependencies": {
"tweetnacl": "^0.14.3"
}
},
- "bluebird": {
+ "node_modules/bluebird": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ=="
},
- "brotli": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
- "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
- "requires": {
- "base64-js": "^1.1.2"
+ "node_modules/brace-expansion": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+ "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "caseless": {
+ "node_modules/caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
},
- "combined-stream": {
+ "node_modules/chai": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
+ "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "requires": {
+ "dependencies": {
"delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
}
},
- "core-util-is": {
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
},
- "dashdash": {
+ "node_modules/dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
- "requires": {
+ "license": "MIT",
+ "dependencies": {
"assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
}
},
- "delayed-stream": {
+ "node_modules/date-fns": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
+ "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/kossnocorp"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
},
- "ecc-jsbn": {
+ "node_modules/ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
- "requires": {
+ "license": "MIT",
+ "dependencies": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
- "extend": {
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz",
+ "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
+ "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.7",
+ "@esbuild/android-arm": "0.27.7",
+ "@esbuild/android-arm64": "0.27.7",
+ "@esbuild/android-x64": "0.27.7",
+ "@esbuild/darwin-arm64": "0.27.7",
+ "@esbuild/darwin-x64": "0.27.7",
+ "@esbuild/freebsd-arm64": "0.27.7",
+ "@esbuild/freebsd-x64": "0.27.7",
+ "@esbuild/linux-arm": "0.27.7",
+ "@esbuild/linux-arm64": "0.27.7",
+ "@esbuild/linux-ia32": "0.27.7",
+ "@esbuild/linux-loong64": "0.27.7",
+ "@esbuild/linux-mips64el": "0.27.7",
+ "@esbuild/linux-ppc64": "0.27.7",
+ "@esbuild/linux-riscv64": "0.27.7",
+ "@esbuild/linux-s390x": "0.27.7",
+ "@esbuild/linux-x64": "0.27.7",
+ "@esbuild/netbsd-arm64": "0.27.7",
+ "@esbuild/netbsd-x64": "0.27.7",
+ "@esbuild/openbsd-arm64": "0.27.7",
+ "@esbuild/openbsd-x64": "0.27.7",
+ "@esbuild/openharmony-arm64": "0.27.7",
+ "@esbuild/sunos-x64": "0.27.7",
+ "@esbuild/win32-arm64": "0.27.7",
+ "@esbuild/win32-ia32": "0.27.7",
+ "@esbuild/win32-x64": "0.27.7"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.3.0.tgz",
+ "integrity": "sha512-XbEXaRva5cF0ZQB8w6MluHA0kZZfV2DuCMJ3ozyEOHLwDpZX2Lmm/7Pp0xdJmI0GL1W05VH5VwIFHEm1Vcw2gw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.2",
+ "@eslint/config-array": "^0.23.5",
+ "@eslint/config-helpers": "^0.5.5",
+ "@eslint/core": "^1.2.1",
+ "@eslint/plugin-kit": "^0.7.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.14.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^9.1.2",
+ "eslint-visitor-keys": "^5.0.1",
+ "espree": "^11.2.0",
+ "esquery": "^1.7.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "minimatch": "^10.2.4",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.8",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
+ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-config-prettier"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz",
+ "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@types/esrecurse": "^4.3.1",
+ "@types/estree": "^1.0.8",
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
+ "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz",
+ "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.16.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^5.0.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expect-type": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
+ "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
- "extsprintf": {
+ "node_modules/extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g=="
+ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT"
},
- "fast-deep-equal": {
+ "node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
},
- "fast-json-stable-stringify": {
+ "node_modules/fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
},
- "forever-agent": {
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "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",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw=="
+ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
},
- "getpass": {
+ "node_modules/getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
- "requires": {
+ "license": "MIT",
+ "dependencies": {
"assert-plus": "^1.0.0"
}
},
- "har-schema": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q=="
- },
- "har-validator": {
- "version": "5.1.5",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
- "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
- "requires": {
- "ajv": "^6.12.3",
- "har-schema": "^2.0.0"
- }
- },
- "http-signature": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
- "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
- "requires": {
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz",
+ "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/http-signature": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz",
+ "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==",
+ "license": "MIT",
+ "dependencies": {
"assert-plus": "^1.0.0",
"jsprim": "^2.0.2",
- "sshpk": "^1.14.1"
+ "sshpk": "^1.18.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/ip-address": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
+ "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
}
},
- "is-typedarray": {
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
},
- "isstream": {
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
},
- "jsbn": {
+ "node_modules/jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
+ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
+ "license": "MIT"
},
- "json-schema": {
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
- "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "license": "(AFL-2.1 OR BSD-3-Clause)"
},
- "json-schema-traverse": {
+ "node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
},
- "json-stringify-safe": {
+ "node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
},
- "jsprim": {
+ "node_modules/jsprim": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
"integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
- "requires": {
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.4.0",
"verror": "1.10.0"
}
},
- "lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lit": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.2.tgz",
+ "integrity": "sha512-NF9zbsP79l4ao2SNrH3NkfmFgN/hBYSQo90saIVI1o5GpjAdCPVstVzO1MrLOakHoEhYkrtRjPK6Ob521aoYWQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit/reactive-element": "^2.1.0",
+ "lit-element": "^4.2.0",
+ "lit-html": "^3.3.0"
+ }
+ },
+ "node_modules/lit-element": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.2.tgz",
+ "integrity": "sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@lit-labs/ssr-dom-shim": "^1.5.0",
+ "@lit/reactive-element": "^2.1.0",
+ "lit-html": "^3.3.0"
+ }
+ },
+ "node_modules/lit-html": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.2.tgz",
+ "integrity": "sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@types/trusted-types": "^2.0.2"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
},
- "mime-db": {
+ "node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
},
- "mime-types": {
+ "node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "requires": {
+ "dependencies": {
"mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.5"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.12",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+ "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
- "oauth-sign": {
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "engines": {
+ "node": "*"
+ }
},
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
- },
- "postman-request": {
- "version": "2.88.1-postman.33",
- "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.33.tgz",
- "integrity": "sha512-uL9sCML4gPH6Z4hreDWbeinKU0p0Ke261nU7OvII95NU22HN6Dk7T/SaVPaj6T4TsQqGKIFw6/woLZnH7ugFNA==",
- "requires": {
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/obug": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
+ "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/sxzz",
+ "https://opencollective.com/debug"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/playwright": {
+ "version": "1.60.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz",
+ "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.60.0"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/playwright-core": {
+ "version": "1.60.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz",
+ "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/pngjs": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz",
+ "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.19.0"
+ }
+ },
+ "node_modules/polarity-integration-utils": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/polarity-integration-utils/-/polarity-integration-utils-4.1.0.tgz",
+ "integrity": "sha512-WcrOJ8CQ/FPcfk5C37QeagOVdzEDE/CumxwVeBoDkCKsOtByDe4u2zcQGwP+o0Ws4xnlfbNVa5lOKgL6KZgpWw==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.18.1",
+ "postman-request": "^2.88.1-postman.48"
+ },
+ "peerDependencies": {
+ "@polarityio/integration-types": ">=1.1.0"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.14",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz",
+ "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postman-request": {
+ "version": "2.88.1-postman.48",
+ "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.48.tgz",
+ "integrity": "sha512-E32FGh8ig2KDvzo4Byi7Ibr+wK2gNKPSqXoNsvjdCHgDBxSK4sCUwv+aa3zOBUwfiibPImHMy0WdlDSSCTqTuw==",
+ "license": "Apache-2.0",
+ "dependencies": {
"@postman/form-data": "~3.1.1",
"@postman/tough-cookie": "~4.1.3-postman.1",
- "@postman/tunnel-agent": "^0.6.3",
+ "@postman/tunnel-agent": "^0.6.8",
"aws-sign2": "~0.7.0",
"aws4": "^1.12.0",
- "brotli": "^1.3.3",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
- "har-validator": "~5.1.3",
- "http-signature": "~1.3.1",
+ "http-signature": "~1.4.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "^2.1.35",
"oauth-sign": "~0.9.0",
- "performance-now": "^2.1.0",
- "qs": "~6.5.3",
+ "qs": "~6.14.1",
"safe-buffer": "^5.1.2",
+ "socks-proxy-agent": "^8.0.5",
"stream-length": "^1.0.2",
"uuid": "^8.3.2"
+ },
+ "engines": {
+ "node": ">= 16"
}
},
- "psl": {
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
+ "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/psl": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
},
- "punycode": {
+ "node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "engines": {
+ "node": ">=6"
+ }
},
- "qs": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
- "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA=="
+ "node_modules/qs": {
+ "version": "6.14.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
+ "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
- "querystringify": {
+ "node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
- "requires-port": {
+ "node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
},
- "safe-buffer": {
+ "node_modules/rollup": {
+ "version": "4.60.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz",
+ "integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.60.3",
+ "@rollup/rollup-android-arm64": "4.60.3",
+ "@rollup/rollup-darwin-arm64": "4.60.3",
+ "@rollup/rollup-darwin-x64": "4.60.3",
+ "@rollup/rollup-freebsd-arm64": "4.60.3",
+ "@rollup/rollup-freebsd-x64": "4.60.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.60.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.60.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.60.3",
+ "@rollup/rollup-linux-arm64-musl": "4.60.3",
+ "@rollup/rollup-linux-loong64-gnu": "4.60.3",
+ "@rollup/rollup-linux-loong64-musl": "4.60.3",
+ "@rollup/rollup-linux-ppc64-gnu": "4.60.3",
+ "@rollup/rollup-linux-ppc64-musl": "4.60.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.60.3",
+ "@rollup/rollup-linux-riscv64-musl": "4.60.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.60.3",
+ "@rollup/rollup-linux-x64-gnu": "4.60.3",
+ "@rollup/rollup-linux-x64-musl": "4.60.3",
+ "@rollup/rollup-openbsd-x64": "4.60.3",
+ "@rollup/rollup-openharmony-arm64": "4.60.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.60.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.60.3",
+ "@rollup/rollup-win32-x64-gnu": "4.60.3",
+ "@rollup/rollup-win32-x64-msvc": "4.60.3",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rollup/node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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=="
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
},
- "safer-buffer": {
+ "node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
},
- "sax": {
+ "node_modules/sax": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
"integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA=="
},
- "sshpk": {
+ "node_modules/semver": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
+ "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
+ "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/sirv": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+ "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz",
+ "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==",
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^10.1.1",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sshpk": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
"integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
- "requires": {
+ "license": "MIT",
+ "dependencies": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
@@ -347,71 +3933,495 @@
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
}
},
- "stream-length": {
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/std-env": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz",
+ "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/stream-length": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/stream-length/-/stream-length-1.0.2.tgz",
"integrity": "sha512-aI+qKFiwoDV4rsXiS7WRoCt+v2RX1nUj17+KJC5r2gfh5xoSJIfP6Y3Do/HtvesFcTSWthIuJ3l1cvKQY/+nZg==",
- "requires": {
+ "dependencies": {
"bluebird": "^2.6.2"
}
},
- "tweetnacl": {
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz",
+ "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.16",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
+ "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz",
+ "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
+ "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
+ "license": "Unlicense"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.59.3",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.3.tgz",
+ "integrity": "sha512-KgusgyDgG4LI8Ih/sWaCtZ06tckLAS5CvT5A4D1Q7bYVoAAyzwiZvE4BmwDHkhRVkvhRBepKeASoFzQetha7Fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.59.3",
+ "@typescript-eslint/parser": "8.59.3",
+ "@typescript-eslint/typescript-estree": "8.59.3",
+ "@typescript-eslint/utils": "8.59.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.21.0.tgz",
+ "integrity": "sha512-w9IMgQrz4O0YN1LtB7K5P63vhlIOvC7opSmouCJ+ZywlPAlO9gIkJ+otk6LvGpAs2wg4econaCz3TvQ9xPoyuQ==",
+ "dev": true,
+ "license": "MIT"
},
- "universalify": {
+ "node_modules/universalify": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
},
- "uri-js": {
+ "node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "requires": {
+ "dev": true,
+ "dependencies": {
"punycode": "^2.1.0"
}
},
- "url-parse": {
+ "node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
- "requires": {
+ "dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
- "uuid": {
+ "node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
},
- "verror": {
+ "node_modules/verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
- "requires": {
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "license": "MIT",
+ "dependencies": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
},
- "xml2js": {
+ "node_modules/vite": {
+ "version": "7.3.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz",
+ "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.27.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.6.tgz",
+ "integrity": "sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/expect": "4.1.6",
+ "@vitest/mocker": "4.1.6",
+ "@vitest/pretty-format": "4.1.6",
+ "@vitest/runner": "4.1.6",
+ "@vitest/snapshot": "4.1.6",
+ "@vitest/spy": "4.1.6",
+ "@vitest/utils": "4.1.6",
+ "es-module-lexer": "^2.0.0",
+ "expect-type": "^1.3.0",
+ "magic-string": "^0.30.21",
+ "obug": "^2.1.1",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.3",
+ "std-env": "^4.0.0-rc.1",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^1.0.2",
+ "tinyglobby": "^0.2.15",
+ "tinyrainbow": "^3.1.0",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^20.0.0 || ^22.0.0 || >=24.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@opentelemetry/api": "^1.9.0",
+ "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
+ "@vitest/browser-playwright": "4.1.6",
+ "@vitest/browser-preview": "4.1.6",
+ "@vitest/browser-webdriverio": "4.1.6",
+ "@vitest/coverage-istanbul": "4.1.6",
+ "@vitest/coverage-v8": "4.1.6",
+ "@vitest/ui": "4.1.6",
+ "happy-dom": "*",
+ "jsdom": "*",
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser-playwright": {
+ "optional": true
+ },
+ "@vitest/browser-preview": {
+ "optional": true
+ },
+ "@vitest/browser-webdriverio": {
+ "optional": true
+ },
+ "@vitest/coverage-istanbul": {
+ "optional": true
+ },
+ "@vitest/coverage-v8": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ },
+ "vite": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.20.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz",
+ "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml2js": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz",
"integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==",
- "requires": {
+ "dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
}
},
- "xmlbuilder": {
+ "node_modules/xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
- "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
}
}
}
diff --git a/package.json b/package.json
index 029b409..f64f275 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,44 @@
{
"name": "qualys",
- "version": "3.2.1",
- "main": "./integration.js",
+ "version": "3.4.0",
+ "main": "./dist/integration.js",
"private": true,
- "license": "MIT",
+ "license": "UNLICENSED",
"author": "Polarity",
"dependencies": {
"lodash": "^4.17.21",
- "postman-request": "^2.88.1-postman.33",
+ "polarity-integration-utils": "^4.1.0",
"xml2js": "^0.6.2"
+ },
+ "devDependencies": {
+ "@eslint/js": "^10.0.1",
+ "@polarityio/integration-types": "^1.1.0",
+ "@polarityio/pi-components": "^1.9.3",
+ "@polarityio/vite-plugin-icl": "^1.0.1",
+ "@types/lodash": "^4.17.24",
+ "@types/xml2js": "^0.4.14",
+ "@vitest/browser": "^4.1.4",
+ "@vitest/browser-playwright": "^4.1.4",
+ "eslint": "^10.2.0",
+ "eslint-config-prettier": "^10.1.8",
+ "lit": "^3.3.2",
+ "playwright": "^1.59.1",
+ "prettier": "^3.8.3",
+ "typescript": "^5.9.3",
+ "typescript-eslint": "^8.58.2",
+ "vite": "^7.3.2",
+ "vitest": "^4.1.4"
+ },
+ "scripts": {
+ "build": "tsc && vite build",
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.web.json",
+ "lint": "eslint src/ web-components/",
+ "lint:fix": "eslint src/ web-components/ --fix",
+ "format": "prettier --write 'src/**/*.ts' 'web-components/**/*.ts'",
+ "format:check": "prettier --check 'src/**/*.ts' 'web-components/**/*.ts'",
+ "test": "vitest run",
+ "test:server": "vitest run --project server",
+ "test:browser": "vitest run --project browser",
+ "test:watch": "vitest"
}
-}
+}
\ No newline at end of file
diff --git a/src/associateDataWithEntities.js b/src/associateDataWithEntities.js
deleted file mode 100644
index 89b6631..0000000
--- a/src/associateDataWithEntities.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const { map, toLower, filter, flow, replace, includes, get, concat, uniqBy, flatMap } = require('lodash/fp');
-
-const associateDataWithEntities = (
- entities,
- { allHostDetections, allFoundKnowledgeBaseRecords },
- Logger
-) =>
- map((entity) => {
- const knowledgeBaseRecords = getObjectsContainingString(
- entity.value,
- allFoundKnowledgeBaseRecords
- );
- const hostDetections = flow(
- flatMap(({ qid }) => getObjectsContainingString(qid, allHostDetections)),
- concat(getObjectsContainingString(entity.value, allHostDetections)),
- uniqBy('id')
- )(knowledgeBaseRecords);
-
- return {
- entity,
- results: {
- hostDetections,
- knowledgeBaseRecords
- }
- };
- }, entities);
-
-const getObjectsContainingString = (string, objs) =>
- filter(
- flow(
- JSON.stringify,
- replace(/[^\w]/g, ''),
- toLower,
- includes(flow(replace(/[^\w]/g, ''), toLower)(string))
- ),
- objs
- );
-
-module.exports = associateDataWithEntities;
diff --git a/src/associateDataWithEntities.ts b/src/associateDataWithEntities.ts
new file mode 100644
index 0000000..e695f80
--- /dev/null
+++ b/src/associateDataWithEntities.ts
@@ -0,0 +1,47 @@
+import { map, toLower, filter, flow, replace, includes, concat, uniqBy, flatMap } from 'lodash/fp';
+import type { Entity } from '@polarityio/integration-types';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+export interface EntityData {
+ allHostDetections: any[];
+ allFoundKnowledgeBaseRecords: any[] | undefined;
+}
+
+export interface EntityWithResults {
+ entity: Entity;
+ results: {
+ hostDetections: any[];
+ knowledgeBaseRecords: any[];
+ };
+}
+
+const associateDataWithEntities = (
+ entities: Entity[],
+ { allHostDetections, allFoundKnowledgeBaseRecords }: EntityData
+): EntityWithResults[] =>
+ map((entity: Entity) => {
+ const knowledgeBaseRecords = getObjectsContainingString(
+ entity.value,
+ allFoundKnowledgeBaseRecords || []
+ );
+ const hostDetections = flow(
+ flatMap(({ qid }: any) => getObjectsContainingString(qid, allHostDetections)),
+ concat(getObjectsContainingString(entity.value, allHostDetections)),
+ uniqBy('id')
+ )(knowledgeBaseRecords);
+ return { entity, results: { hostDetections, knowledgeBaseRecords } };
+ }, entities);
+
+const getObjectsContainingString = (string: string, objs: any[]): any[] =>
+ filter(
+ flow(
+ JSON.stringify,
+ replace(/[^\w]/g, ''),
+ toLower,
+ includes(flow(replace(/[^\w]/g, ''), toLower)(string))
+ ),
+ objs
+ );
+
+export default associateDataWithEntities;
diff --git a/src/constants.js b/src/constants.ts
similarity index 66%
rename from src/constants.js
rename to src/constants.ts
index 8672634..f005970 100644
--- a/src/constants.js
+++ b/src/constants.ts
@@ -1,12 +1,9 @@
-const IGNORED_IPS = new Set(['127.0.0.1', '255.255.255.255', '0.0.0.0']);
+export const IGNORED_IPS = new Set(['127.0.0.1', '255.255.255.255', '0.0.0.0']);
-const QUERY_PATHS_BY_TYPE = {
+export const QUERY_PATHS_BY_TYPE: Record> = {
qid: {
assets: ['name'],
- vulnerabilities: [
- 'vulnerabilities.vulnerability.qid',
- 'vulnerabilities.vulnerability.title'
- ]
+ vulnerabilities: ['vulnerabilities.vulnerability.qid', 'vulnerabilities.vulnerability.title']
},
cve: {
assets: ['name'],
@@ -14,38 +11,45 @@ const QUERY_PATHS_BY_TYPE = {
},
domain: {
assets: ['name', 'interfaces.hostname'],
- vulnerabilities: [
- 'vulnerabilities.hostAssetName',
- 'vulnerabilities.vulnerability.title'
- ]
+ vulnerabilities: ['vulnerabilities.hostAssetName', 'vulnerabilities.vulnerability.title']
},
IPv4: {
- assets: [
- 'interfaces.address',
- 'name',
- 'interfaces.dnsAddress',
- 'interfaces.gatewayAddress'
- ],
+ assets: ['interfaces.address', 'name', 'interfaces.dnsAddress', 'interfaces.gatewayAddress'],
vulnerabilities: ['vulnerabilities.vulnerability.title']
},
IPv6: {
- assets: [
- 'interfaces.address',
- 'name',
- 'interfaces.dnsAddress',
- 'interfaces.gatewayAddress'
- ],
+ assets: ['interfaces.address', 'name', 'interfaces.dnsAddress', 'interfaces.gatewayAddress'],
vulnerabilities: ['vulnerabilities.vulnerability.title']
}
};
+QUERY_PATHS_BY_TYPE.customType = QUERY_PATHS_BY_TYPE.qid;
-const SEARCH_COLUMN_NAMES_BY_TYPE = {
+export const SEARCH_COLUMN_NAMES_BY_TYPE: Record = {
cve: ['title', 'category', 'diagnosis', 'solution', 'cves', 'vender_references'],
qid: ['qid'],
default: ['title', 'diagnosis', 'solution', 'vender_references']
};
-const HOST_DETECTION_DISPLAY_FORMAT = {
+export interface DisplayFormatEntry {
+ label?: string;
+ isTitle?: boolean;
+ isDate?: boolean;
+ isList?: boolean;
+ isListOfLinks?: boolean;
+ isHtml?: boolean;
+ isNewSectionLineBreak?: boolean;
+ indent?: number;
+ collapsibleListItems?: boolean;
+ showLabelAndValue?: boolean;
+ fieldIsCopyable?: boolean;
+ shouldCopyFieldLabel?: boolean;
+ itemDisplayFormat?: DisplayFormat;
+}
+
+export type DisplayFormatValue = string | DisplayFormatEntry;
+export type DisplayFormat = Record;
+
+export const HOST_DETECTION_DISPLAY_FORMAT: DisplayFormat = {
ip: { label: 'IP Address', isTitle: true, showLabelAndValue: true },
id: 'Host Detection ID',
asset_id: 'Asset Id',
@@ -82,7 +86,7 @@ const HOST_DETECTION_DISPLAY_FORMAT = {
newSectionLineBreak: { isNewSectionLineBreak: true }
};
-const KNOWLEDGE_BASE_RECORD_DISPLAY_FORMAT = {
+export const KNOWLEDGE_BASE_RECORD_DISPLAY_FORMAT: DisplayFormat = {
title: { isTitle: true },
qid: { label: 'QID', fieldIsCopyable: true, shouldCopyFieldLabel: true },
severity: 'Severity',
@@ -100,12 +104,4 @@ const KNOWLEDGE_BASE_RECORD_DISPLAY_FORMAT = {
diagnosis: { label: 'Diagnosis', isHtml: true },
solution: { label: 'Solution', isHtml: true },
newSectionLineBreak: { isNewSectionLineBreak: true }
-};
-
-module.exports = {
- IGNORED_IPS,
- QUERY_PATHS_BY_TYPE,
- SEARCH_COLUMN_NAMES_BY_TYPE,
- KNOWLEDGE_BASE_RECORD_DISPLAY_FORMAT,
- HOST_DETECTION_DISPLAY_FORMAT
-};
+};
\ No newline at end of file
diff --git a/src/createLookupResults.js b/src/createLookupResults.js
deleted file mode 100644
index 8696fb9..0000000
--- a/src/createLookupResults.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const {
- flow,
- get,
- map,
- size,
- mapValues,
- some,
- identity,
- keys,
- assign,
- eq
-} = require('lodash/fp');
-
-const { HOST_DETECTION_DISPLAY_FORMAT } = require('./constants');
-const getDisplayResults = require('./getDisplayResults');
-
-const createLookupResults = (foundEntities, Logger) =>
- map(({ entity, results }) => {
- const formattedQueryResult = formatQueryResult(results);
-
- const lookupResult = {
- entity,
- displayValue: entity.type === 'qid' ? `QID: ${entity.value}` : entity.value,
- data: !!formattedQueryResult
- ? {
- summary: createSummary(entity, results, Logger),
- details: flow(keys, (keys) =>
- assign(formattedQueryResult, {
- tabKeys: keys
- })
- )(formattedQueryResult)
- }
- : null
- };
-
- return lookupResult;
- }, foundEntities);
-
-const createSummary = (entity, { hostDetections, knowledgeBaseRecords }, Logger) =>
- [].concat(size(hostDetections) ? `Host Detections: ${size(hostDetections)}` : []);
-
-const formatQueryResult = (result) => {
- const resultNotEmpty = flow(mapValues(size), some(identity))(result);
-
- if (resultNotEmpty) {
- const hostDetections = getDisplayResults(
- HOST_DETECTION_DISPLAY_FORMAT,
- result.hostDetections
- );
-
- return {
- hostDetections
- };
- }
-};
-
-module.exports = createLookupResults;
diff --git a/src/createLookupResults.ts b/src/createLookupResults.ts
new file mode 100644
index 0000000..c8170d5
--- /dev/null
+++ b/src/createLookupResults.ts
@@ -0,0 +1,46 @@
+import { flow, map, size, mapValues, some, identity, keys, assign } from 'lodash/fp';
+import type { Entity } from '@polarityio/integration-types';
+import type { LookupResult } from '@polarityio/integration-types';
+
+import { HOST_DETECTION_DISPLAY_FORMAT } from './constants';
+import getDisplayResults from './getDisplayResults';
+import type { EntityWithResults } from './associateDataWithEntities';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+const createLookupResults = (foundEntities: EntityWithResults[]): LookupResult[] =>
+ map(({ entity, results }: EntityWithResults) => {
+ const formattedQueryResult = formatQueryResult(results);
+ const lookupResult: LookupResult = {
+ entity,
+ displayValue: (entity.type as string) === 'qid' ? `QID: ${entity.value}` : entity.value,
+ data: formattedQueryResult
+ ? {
+ summary: createSummary(entity, results),
+ details: flow(keys, (k: string[]) => assign(formattedQueryResult, { tabKeys: k }))(
+ formattedQueryResult
+ )
+ }
+ : null
+ };
+ return lookupResult;
+ }, foundEntities);
+
+const createSummary = (
+ _entity: Entity,
+ { hostDetections }: { hostDetections: any[]; knowledgeBaseRecords: any[] }
+): string[] =>
+ ([] as string[]).concat(size(hostDetections) ? `Host Detections: ${size(hostDetections)}` : []);
+
+const formatQueryResult = (result: {
+ hostDetections: any[];
+ knowledgeBaseRecords: any[];
+}): Record | undefined => {
+ const resultNotEmpty = flow(mapValues(size), some(identity))(result);
+ if (resultNotEmpty) {
+ const hostDetections = getDisplayResults(HOST_DETECTION_DISPLAY_FORMAT, result.hostDetections);
+ return { hostDetections };
+ }
+};
+
+export default createLookupResults;
diff --git a/src/createRequestWithDefaults.js b/src/createRequestWithDefaults.js
deleted file mode 100644
index 21aa6dd..0000000
--- a/src/createRequestWithDefaults.js
+++ /dev/null
@@ -1,115 +0,0 @@
-const fs = require('fs');
-const { identity, omit } = require('lodash/fp');
-const request = require('postman-request');
-const config = require('../config/config');
-const { parseErrorToReadableJSON } = require('./dataTransformations');
-
-const SUCCESSFUL_ROUNDED_REQUEST_STATUS_CODES = [200];
-
-const _configFieldIsValid = (field) => typeof field === 'string' && field.length > 0;
-
-const createRequestWithDefaults = (Logger) => {
- const {
- request: { ca, cert, key, passphrase, rejectUnauthorized, proxy }
- } = config;
-
- const defaults = {
- ...(_configFieldIsValid(ca) && { ca: fs.readFileSync(ca) }),
- ...(_configFieldIsValid(cert) && { cert: fs.readFileSync(cert) }),
- ...(_configFieldIsValid(key) && { key: fs.readFileSync(key) }),
- ...(_configFieldIsValid(passphrase) && { passphrase }),
- ...(_configFieldIsValid(proxy) && { proxy }),
- ...(typeof rejectUnauthorized === 'boolean' && { rejectUnauthorized }),
- json: true
- };
-
- const requestWithDefaults = (
- preRequestFunction = async () => ({}),
- postRequestSuccessFunction = async (x) => x,
- postRequestFailureFunction = async (e) => {
- throw e;
- }
- ) => {
- const defaultsRequest = request.defaults(defaults);
-
- const _requestWithDefault = (requestOptions) =>
- new Promise((resolve, reject) => {
- defaultsRequest(requestOptions, (err, res, body) => {
- if (err) return reject(err);
- resolve({ ...res, body });
- });
- });
-
- return async (requestOptions) => {
- const preRequestFunctionResults = await preRequestFunction(requestOptions);
- const _requestOptions = {
- ...requestOptions,
- ...preRequestFunctionResults
- };
-
- let postRequestFunctionResults;
- try {
- const result = await _requestWithDefault(_requestOptions);
- checkForStatusError(result, _requestOptions);
-
- postRequestFunctionResults = await postRequestSuccessFunction(
- result,
- _requestOptions
- );
- } catch (error) {
- postRequestFunctionResults = await postRequestFailureFunction(
- error,
- _requestOptions
- );
- }
- return postRequestFunctionResults;
- };
- };
-
- const handleAuth = async ({ options, ...requestOptions }) => ({
- ...requestOptions,
- auth: {
- username: options.username,
- password: options.password,
- }
- });
-
- const checkForStatusError = ({ statusCode, body }, requestOptions) => {
- Logger.trace({
- requestOptions: {
- ...requestOptions,
- auth: '************',
- options: '************'
- },
- statusCode,
- body
- });
-
- const roundedStatus = Math.round(statusCode / 100) * 100;
- if (!SUCCESSFUL_ROUNDED_REQUEST_STATUS_CODES.includes(roundedStatus)) {
- const requestError = Error('Request Error');
- requestError.status = statusCode;
- requestError.description = JSON.stringify(body);
- requestError.requestOptions = JSON.stringify(requestOptions);
- throw requestError;
- }
- };
-
- const requestDefaultsWithInterceptors = requestWithDefaults(handleAuth, identity, (error) => {
- const err = parseErrorToReadableJSON(error);
- if (err.requestOptions && ['{', '['].includes(err.requestOptions[0]))
- err.requestOptions = omit(['options', 'auth'], JSON.parse(err.requestOptions));
-
- Logger.error({ err });
- let newError = new Error(err.message)
- newError.status = err.status;
- newError.requestOptions = JSON.stringify(err.requestOptions);
- newError.description = err.description;
- newError.stack = err.stack;
- throw newError;
- });
-
- return requestDefaultsWithInterceptors;
-};
-
-module.exports = createRequestWithDefaults;
diff --git a/src/dataTransformations.js b/src/dataTransformations.js
deleted file mode 100644
index 0937448..0000000
--- a/src/dataTransformations.js
+++ /dev/null
@@ -1,216 +0,0 @@
-const _ = require('lodash');
-const {
- flow,
- keys,
- values,
- zipObject,
- map,
- first,
- omit,
- reduce,
- size,
- negate,
- curry,
- filter,
- eq,
- isEmpty,
- getOr,
- join,
- get,
- isArray,
- identity
-} = require('lodash/fp');
-
-const { IGNORED_IPS, QUERY_PATHS_BY_TYPE } = require('./constants');
-
-const getKeys = (keys, items) =>
- Array.isArray(items)
- ? items.map((item) => _.pickBy(item, (v, key) => keys.includes(key)))
- : _.pickBy(items, (v, key) => keys.includes(key));
-
-const groupEntities = (entities) =>
- _.chain(entities)
- .groupBy(({ isIP, isDomain, type }) =>
- isIP
- ? 'ip'
- : isDomain
- ? 'domain'
- : type === 'MAC'
- ? 'mac'
- : type === 'MD5'
- ? 'md5'
- : type === 'SHA1'
- ? 'sha1'
- : type === 'SHA256'
- ? 'sha256'
- : 'unknown'
- )
- .omit('unknown')
- .value();
-
-const splitOutIgnoredIps = (_entitiesPartition) => {
- const { ignoredIPs, entitiesPartition } = _.groupBy(
- _entitiesPartition,
- ({ isIP, value }) =>
- !isIP || (isIP && !IGNORED_IPS.has(value)) ? 'entitiesPartition' : 'ignoredIPs'
- );
-
- return {
- entitiesPartition,
- ignoredIpLookupResults: _.map(ignoredIPs, (entity) => ({
- entity,
- data: null
- }))
- };
-};
-
-const objectPromiseAll = async (obj = { fn1: async () => {} }) => {
- const labels = keys(obj);
- const functions = values(obj);
- const executedFunctions = await Promise.all(map((func) => func(), functions));
-
- return zipObject(labels, executedFunctions);
-};
-
-const asyncObjectReduce = async (func, initAgg, obj) => {
- const nextKey = flow(keys, first)(obj);
-
- if (!nextKey) return initAgg;
-
- const newAgg = await func(initAgg, obj[nextKey], nextKey);
-
- return await asyncObjectReduce(func, newAgg, omit(nextKey, obj));
-};
-
-const transpose2DArray = reduce(
- (agg, [key, value]) => [
- [...agg[0], key],
- [...agg[1], value]
- ],
- [[], []]
-);
-
-const or =
- (...[func, ...funcs]) =>
- (x) =>
- func(x) || (funcs.length && or(...funcs)(x));
-
-const and =
- (...[func, ...funcs]) =>
- (x) =>
- func(x) && (funcs.length ? and(...funcs)(x) : true);
-
-// func: (value, key) => [newKey, newValue], obj: { key1:value1, key2:value2 }
-// return { newKey1: newValue1, newKey2: newValue2 }
-const mapObject = curry((func, obj) =>
- flow(
- Object.entries,
- map(([key, value]) => func(value, key)),
- filter(and(negate(isEmpty), flow(size, eq(2)))),
- transpose2DArray,
- ([keys, values]) => zipObject(keys, values)
- )(obj)
-);
-
-const mapObjectAsync = async (func, obj) => {
- // func: (value, key) => [newKey, newValue], obj: { key1:value1, key2:value2 }
- // return { newKey1: newValue1, newKey2: newValue2 }
- const unzippedResults = await Promise.all(
- map(async ([key, value]) => await func(value, key), Object.entries(obj))
- );
-
- return flow(
- filter(and(negate(isEmpty), flow(size, eq(2)))),
- transpose2DArray,
- ([keys, values]) => zipObject(keys, values)
- )(unzippedResults);
-};
-
-const parseErrorToReadableJSON = (error) =>
- JSON.parse(JSON.stringify(error, Object.getOwnPropertyNames(error)));
-
-const buildQueryByQueryType = (queryType, entities) =>
- flow(
- map((entity) =>
- flow(
- getOr([], [entity.type, queryType]),
- map((queryPath) => `${queryPath}: "${entity.value}"`),
- join(' OR ')
- )(QUERY_PATHS_BY_TYPE)
- ),
- join(' OR ')
- )(entities);
-
-const millisToHoursMinutesAndSeconds = (millis) => {
- let remainingMillis = millis;
-
- const seconds = Math.floor((remainingMillis / 1000) % 60);
- remainingMillis -= seconds * 1000;
-
- const minutes = Math.floor((remainingMillis / 60000) % 60);
- remainingMillis -= minutes * 60000;
-
- const hours = Math.floor(remainingMillis / 3600000);
-
- return (
- (hours ? `${hours} hours, ` : '') +
- (minutes ? `${minutes} minutes, ` : '') +
- (seconds ? `${seconds} seconds` : '') +
- (!hours && !minutes && !seconds ? `${millis}ms` : '')
- );
-};
-
-const processResultWithProcessingFormat = (processingFormat) => (result) =>
- mapObject(
- (value, key) => [
- key,
- typeof value === 'string'
- ? get(value, result)
- : flow(get(value.path), value.process)(result)
- ],
- processingFormat
- );
-
-const processPossibleList =
- (shouldStringify = true) =>
- (arrayOrObject) =>
- arrayOrObject &&
- (shouldStringify ? JSON.stringify : identity)(
- isArray(arrayOrObject) ? arrayOrObject : [arrayOrObject]
- );
-
-const xml2js = require('xml2js');
-
-const xmlToJson = async (xml, Logger) => {
- try {
- const parser = new xml2js.Parser({
- normalizeTags: true,
- explicitArray: false,
- charkey: 'value',
- attrkey: 'attributes'
- });
- return await parser.parseStringPromise(xml);
- } catch (e) {
- const err = parseErrorToReadableJSON(e);
- Logger.error({ MESSAGE: 'Failed to Parse XML', xml, err });
- }
-};
-
-module.exports = {
- getKeys,
- groupEntities,
- splitOutIgnoredIps,
- objectPromiseAll,
- asyncObjectReduce,
- mapObject,
- mapObjectAsync,
- transpose2DArray,
- parseErrorToReadableJSON,
- buildQueryByQueryType,
- millisToHoursMinutesAndSeconds,
- processResultWithProcessingFormat,
- processPossibleList,
- xmlToJson,
- and,
- or
-};
diff --git a/src/dataTransformations.ts b/src/dataTransformations.ts
new file mode 100644
index 0000000..c022dc7
--- /dev/null
+++ b/src/dataTransformations.ts
@@ -0,0 +1,211 @@
+import _ from 'lodash';
+import {
+ flow,
+ keys,
+ values,
+ zipObject,
+ map,
+ first,
+ omit,
+ reduce,
+ size,
+ curry,
+ filter,
+ eq,
+ isEmpty,
+ getOr,
+ join,
+ get,
+ isArray,
+ identity
+} from 'lodash/fp';
+import * as xml2js from 'xml2js';
+import type { Logger } from '@polarityio/integration-types';
+import type { Entity } from '@polarityio/integration-types';
+
+import { IGNORED_IPS, QUERY_PATHS_BY_TYPE } from './constants';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+export const getKeys = (keyList: string[], items: any): any =>
+ Array.isArray(items)
+ ? items.map((item: any) => _.pickBy(item, (_v: any, key: string) => keyList.includes(key)))
+ : _.pickBy(items, (_v: any, key: string) => keyList.includes(key));
+
+export const groupEntities = (entities: Entity[]): Record =>
+ _.chain(entities)
+ .groupBy(({ isIP, isDomain, type }: any) =>
+ isIP
+ ? 'ip'
+ : isDomain
+ ? 'domain'
+ : type === 'MAC'
+ ? 'mac'
+ : type === 'MD5'
+ ? 'md5'
+ : type === 'SHA1'
+ ? 'sha1'
+ : type === 'SHA256'
+ ? 'sha256'
+ : 'unknown'
+ )
+ .omit('unknown')
+ .value();
+
+export const splitOutIgnoredIps = (
+ _entitiesPartition: Entity[]
+): { entitiesPartition: Entity[]; ignoredIpLookupResults: any[] } => {
+ const grouped = _.groupBy(_entitiesPartition, ({ isIP, value }: any) =>
+ !isIP || (isIP && !IGNORED_IPS.has(value)) ? 'entitiesPartition' : 'ignoredIPs'
+ );
+
+ return {
+ entitiesPartition: grouped.entitiesPartition || [],
+ ignoredIpLookupResults: _.map(grouped.ignoredIPs, (entity: Entity) => ({
+ entity,
+ data: null
+ }))
+ };
+};
+
+export const objectPromiseAll = async (
+ obj: Record Promise>
+): Promise> => {
+ const labels = keys(obj);
+ const functions = values(obj);
+ const executedFunctions = await Promise.all(map((func: () => Promise) => func(), functions));
+ return zipObject(labels, executedFunctions);
+};
+
+export const asyncObjectReduce = async (
+ func: (agg: any, value: any, key: string) => Promise,
+ initAgg: any,
+ obj: Record
+): Promise => {
+ const nextKey = flow(keys, first)(obj) as string | undefined;
+ if (!nextKey) return initAgg;
+ const newAgg = await func(initAgg, obj[nextKey], nextKey);
+ return await asyncObjectReduce(func, newAgg, omit(nextKey, obj) as Record);
+};
+
+export const transpose2DArray = reduce(
+ (agg: [any[], any[]], [key, value]: [any, any]) =>
+ [
+ [...agg[0], key],
+ [...agg[1], value]
+ ] as [any[], any[]],
+ [[], []] as [any[], any[]]
+);
+
+export const or =
+ (...[func, ...funcs]: Array<(x: any) => boolean>) =>
+ (x: any): boolean =>
+ func(x) || (funcs.length > 0 && or(...funcs)(x));
+
+export const and =
+ (...[func, ...funcs]: Array<(x: any) => boolean>) =>
+ (x: any): boolean =>
+ func(x) && (funcs.length > 0 ? and(...funcs)(x) : true);
+
+const negate =
+ (fn: (x: any) => boolean) =>
+ (x: any): boolean =>
+ !fn(x);
+
+export const mapObject = curry(
+ (func: (value: any, key: string) => any, obj: Record): Record =>
+ flow(
+ Object.entries,
+ map(([key, value]: [string, any]) => func(value, key)),
+ filter(and(negate(isEmpty), flow(size, eq(2)))),
+ transpose2DArray,
+ ([k, v]: [string[], any[]]) => zipObject(k, v)
+ )(obj)
+);
+
+export const mapObjectAsync = async (
+ func: (value: any, key: string) => Promise,
+ obj: Record
+): Promise> => {
+ const unzippedResults = await Promise.all(
+ map(async ([key, value]: [string, any]) => await func(value, key), Object.entries(obj))
+ );
+ return flow(
+ filter(and(negate(isEmpty), flow(size, eq(2)))),
+ transpose2DArray,
+ ([k, v]: [string[], any[]]) => zipObject(k, v)
+ )(unzippedResults);
+};
+
+export const parseErrorToReadableJSON = (error: unknown): Record => {
+ const serialized = JSON.parse(JSON.stringify(error, Object.getOwnPropertyNames(error as object)));
+ delete serialized.config;
+ delete serialized.request;
+ delete serialized.options;
+ delete serialized.auth;
+ return serialized;
+};
+
+export const buildQueryByQueryType = (queryType: string, entities: Entity[]): string =>
+ flow(
+ map((entity: Entity) =>
+ flow(
+ getOr([], [entity.type, queryType]),
+ map((queryPath: string) => `${queryPath}: "${entity.value}"`),
+ join(' OR ')
+ )(QUERY_PATHS_BY_TYPE as any)
+ ),
+ join(' OR ')
+ )(entities);
+
+export const millisToHoursMinutesAndSeconds = (millis: number): string => {
+ let remainingMillis = millis;
+ const seconds = Math.floor((remainingMillis / 1000) % 60);
+ remainingMillis -= seconds * 1000;
+ const minutes = Math.floor((remainingMillis / 60000) % 60);
+ remainingMillis -= minutes * 60000;
+ const hours = Math.floor(remainingMillis / 3600000);
+ return (
+ (hours ? `${hours} hours, ` : '') +
+ (minutes ? `${minutes} minutes, ` : '') +
+ (seconds ? `${seconds} seconds` : '') +
+ (!hours && !minutes && !seconds ? `${millis}ms` : '')
+ );
+};
+
+export const processResultWithProcessingFormat =
+ (processingFormat: Record) =>
+ (result: any): Record =>
+ mapObject(
+ (value: any, key: string) => [
+ key,
+ typeof value === 'string'
+ ? get(value, result)
+ : flow(get(value.path), value.process)(result)
+ ],
+ processingFormat
+ );
+
+export const processPossibleList =
+ (shouldStringify = true) =>
+ (arrayOrObject: any): any =>
+ arrayOrObject &&
+ (shouldStringify ? JSON.stringify : identity)(
+ isArray(arrayOrObject) ? arrayOrObject : [arrayOrObject]
+ );
+
+export const xmlToJson = async (xml: string, Logger: Logger): Promise => {
+ try {
+ const parser = new xml2js.Parser({
+ normalizeTags: true,
+ explicitArray: false,
+ charkey: 'value',
+ attrkey: 'attributes'
+ });
+ return await parser.parseStringPromise(xml);
+ } catch (e) {
+ const err = parseErrorToReadableJSON(e);
+ Logger.error({ MESSAGE: 'Failed to Parse XML', err }, 'XML Parse Failed');
+ Logger.trace({ xml }, 'Raw XML that failed to parse');
+ }
+};
diff --git a/src/getDisplayResults.js b/src/getDisplayResults.js
deleted file mode 100644
index 0fc256c..0000000
--- a/src/getDisplayResults.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const { flow, get, map, values, assign, flatMap } = require('lodash/fp');
-
-const { mapObject } = require('./dataTransformations');
-
-const getDisplayResults = (displayFormat, results, dontFlatten) =>
- (dontFlatten ? map : flatMap)((record) => {
- const displayResultsAsObject = mapObject(
- (contentInfo, columnName) =>
- (get(columnName, record) ||
- get('isTitle', contentInfo) ||
- get('isNewSectionLineBreak', contentInfo)) && [
- columnName,
- buildDisplayValue(contentInfo, columnName, record)
- ],
- displayFormat
- );
-
- const displayResults = values(displayResultsAsObject);
-
- return displayResults;
- }, results);
-
-const buildDisplayValue = (contentInfo, columnName, record) =>
- typeof contentInfo === 'string'
- ? { label: contentInfo, value: get(columnName, record) }
- : assign(contentInfo, {
- value: flow(get(columnName), (value) =>
- contentInfo.isListOfLinks
- ? JSON.parse(value)
- : contentInfo.isList
- ? getDisplayResults(
- contentInfo.itemDisplayFormat,
- get(columnName, record),
- true
- )
- : value
- )(record)
- });
-
-module.exports = getDisplayResults;
diff --git a/src/getDisplayResults.ts b/src/getDisplayResults.ts
new file mode 100644
index 0000000..fb17b34
--- /dev/null
+++ b/src/getDisplayResults.ts
@@ -0,0 +1,48 @@
+import { flow, get, map, values, assign, flatMap } from 'lodash/fp';
+import { mapObject } from './dataTransformations';
+import type { DisplayFormat, DisplayFormatEntry } from './constants';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+const getDisplayResults = (
+ displayFormat: DisplayFormat,
+ results: any[],
+ dontFlatten?: boolean
+): any[] =>
+ (dontFlatten ? map : (flatMap as any))((record: any) => {
+ const displayResultsAsObject = mapObject(
+ (contentInfo: any, columnName: string) =>
+ (get(columnName, record) ||
+ get('isTitle', contentInfo) ||
+ get('isNewSectionLineBreak', contentInfo)) && [
+ columnName,
+ buildDisplayValue(contentInfo, columnName, record)
+ ],
+ displayFormat
+ );
+ const displayResults = values(displayResultsAsObject);
+ return displayResults;
+ }, results);
+
+const buildDisplayValue = (
+ contentInfo: string | DisplayFormatEntry,
+ columnName: string,
+ record: any
+): any =>
+ typeof contentInfo === 'string'
+ ? { label: contentInfo, value: get(columnName, record) }
+ : assign(contentInfo, {
+ value: flow(get(columnName), (value: any) =>
+ (contentInfo as DisplayFormatEntry).isListOfLinks
+ ? JSON.parse(value)
+ : (contentInfo as DisplayFormatEntry).isList
+ ? getDisplayResults(
+ (contentInfo as DisplayFormatEntry).itemDisplayFormat!,
+ get(columnName, record),
+ true
+ )
+ : value
+ )(record)
+ });
+
+export default getDisplayResults;
diff --git a/src/getLookupResults.js b/src/getLookupResults.js
deleted file mode 100644
index 190270f..0000000
--- a/src/getLookupResults.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const { flow, map, split, first, last, trim, concat, get, uniqBy } = require('lodash/fp');
-
-const { splitOutIgnoredIps } = require('./dataTransformations');
-const createLookupResults = require('./createLookupResults');
-const queryHostDetectionListForAllEntities = require('./querying/queryHostDetectionListForAllEntities');
-const associateDataWithEntities = require('./associateDataWithEntities');
-
-const getLookupResults = async (
- entities,
- options,
- requestWithDefaults,
- Logger
-) => {
- const entitiesWithCustomTypesSpecified = map(({ type, types, value, ...entity }) => {
- type = type === 'custom' ? flow(first, split('.'), last)(types) : type;
-
- return {
- ...entity,
- type,
- value: type === 'qid' ? flow(split(':'), last, trim)(value) : value
- };
- }, entities);
-
- const { entitiesPartition, ignoredIpLookupResults } = splitOutIgnoredIps(
- entitiesWithCustomTypesSpecified
- );
-
- const data = await getData(
- entitiesPartition,
- options,
- requestWithDefaults,
- Logger
- );
-
- const foundEntities = associateDataWithEntities(entitiesPartition, data, Logger);
- const lookupResults = createLookupResults(foundEntities, Logger);
-
- return lookupResults.concat(ignoredIpLookupResults);
-};
-
-const getData = async (
- entitiesPartition,
- options,
- requestWithDefaults,
- Logger
-) => {
- const [initialHostDetections, allFoundKnowledgeBaseRecords] = await Promise.all([
- queryHostDetectionListForAllEntities(
- entitiesPartition,
- options,
- requestWithDefaults,
- Logger
- )
- ]);
-
- const allHostDetections = flow(
- uniqBy('id')
- )(initialHostDetections);
-
- Logger.trace({ allHostDetections }, 'All Host Detections');
-
- return { allHostDetections, allFoundKnowledgeBaseRecords };
-};
-
-module.exports = {
- getLookupResults
-};
diff --git a/src/getLookupResults.ts b/src/getLookupResults.ts
new file mode 100644
index 0000000..a6d558a
--- /dev/null
+++ b/src/getLookupResults.ts
@@ -0,0 +1,64 @@
+import { flow, map, split, first, last, uniqBy } from 'lodash/fp';
+import type { Entity, Logger } from '@polarityio/integration-types';
+import type { PolarityRequest } from 'polarity-integration-utils';
+
+import { splitOutIgnoredIps } from './dataTransformations';
+import createLookupResults from './createLookupResults';
+import queryHostDetectionListForAllEntities from './querying/queryHostDetectionListForAllEntities';
+import associateDataWithEntities from './associateDataWithEntities';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+export const getLookupResults = async (
+ entities: Entity[],
+ options: Record,
+ request: PolarityRequest,
+ Logger: Logger
+): Promise => {
+ const entitiesWithCustomTypesSpecified: Entity[] = map((entity: Entity) => {
+ const type: string =
+ entity.type === 'custom'
+ ? (flow(first, split('.'), last)(entity.types) as string)
+ : entity.type;
+
+ const value =
+ type === 'qid'
+ ? (/(?:QID|qid)(?:\s*:\s*|\s+)(\d{1,8})/i.exec(entity.value)?.[1] ?? entity.value)
+ : entity.value;
+
+ if (type === 'customType') {
+ const extractRegex = new RegExp(options.customTypeValueRegex || '\\d+$');
+ const extracted = extractRegex.exec(entity.value)?.[0];
+ if (extracted) {
+ return { ...entity, type, value: extracted } as Entity;
+ }
+ }
+
+ return { ...entity, type, value } as Entity;
+ }, entities);
+
+ const { entitiesPartition, ignoredIpLookupResults } = splitOutIgnoredIps(
+ entitiesWithCustomTypesSpecified
+ );
+
+ const data = await getData(entitiesPartition, options, request, Logger);
+ const foundEntities = associateDataWithEntities(entitiesPartition, data);
+ const lookupResults = createLookupResults(foundEntities);
+ return lookupResults.concat(ignoredIpLookupResults);
+};
+
+const getData = async (
+ entitiesPartition: Entity[],
+ options: Record,
+ request: PolarityRequest,
+ Logger: Logger
+): Promise => {
+ const [initialHostDetections] = await Promise.all([
+ queryHostDetectionListForAllEntities(entitiesPartition, options, request, Logger)
+ ]);
+
+ const allHostDetections = flow(uniqBy('id'))(initialHostDetections);
+ Logger.trace({ allHostDetections }, 'All Host Detections');
+
+ return { allHostDetections, allFoundKnowledgeBaseRecords: undefined };
+};
\ No newline at end of file
diff --git a/src/integration.ts b/src/integration.ts
new file mode 100644
index 0000000..5cf6db6
--- /dev/null
+++ b/src/integration.ts
@@ -0,0 +1,80 @@
+import { PolarityRequest, setLogger } from 'polarity-integration-utils';
+import { IntegrationError } from 'polarity-integration-utils';
+import type {
+ Entity,
+ DoLookupUserOptions,
+ DoLookupResult,
+ Logger,
+ IntegrationContext,
+ ValidateOptionsUserOptions,
+ ValidationError
+} from '@polarityio/integration-types';
+import type { BeforeRequestHook } from 'polarity-integration-utils';
+
+import { parseErrorToReadableJSON } from './dataTransformations';
+import { getLookupResults } from './getLookupResults';
+import { validateStringOptions, validateUrlOption, validateCustomTypeValueRegex } from './validateOptions';
+
+let request: PolarityRequest;
+
+const addAuth: BeforeRequestHook = async (requestOptions, userOptions) => ({
+ ...requestOptions,
+ auth: {
+ username: userOptions.username as string,
+ password: userOptions.password as string
+ }
+});
+
+function startup(logger: Logger): void {
+ setLogger(logger);
+ request = new PolarityRequest({
+ roundedSuccessStatusCodes: [200],
+ hooks: { beforeRequest: [addAuth] }
+ });
+}
+
+async function doLookup(
+ entities: Entity[],
+ options: DoLookupUserOptions,
+ context: IntegrationContext
+): Promise {
+ const Logger = context.logger;
+ Logger.debug({ entities }, 'Entities');
+
+ request.userOptions = options;
+
+ try {
+ const lookupResults = await getLookupResults(entities, options, request, Logger);
+ Logger.trace({ lookupResults }, 'Lookup Results');
+ return lookupResults;
+ } catch (error) {
+ const err = parseErrorToReadableJSON(error);
+ Logger.error({ formattedError: err }, 'Get Lookup Results Failed');
+
+ throw new IntegrationError(
+ (error as Error).message ? (error as Error).message : 'Searching Failed',
+ { cause: error, meta: { formattedError: err } }
+ );
+ }
+}
+
+function validateOptions(
+ options: ValidateOptionsUserOptions,
+ _context: IntegrationContext
+): ValidationError[] {
+ const stringOptionsErrorMessages: Record = {
+ url: 'You must provide a valid Qualys URL.',
+ username: 'You must provide a valid Qualys Username',
+ password: 'You must provide a valid Qualys Password'
+ };
+
+ const stringValidationErrors = validateStringOptions(stringOptionsErrorMessages, options);
+
+ const urlValidationErrors = validateUrlOption(options.url.value as string);
+
+ const customTypeRegexErrors = validateCustomTypeValueRegex(options);
+
+ return stringValidationErrors.concat(urlValidationErrors).concat(customTypeRegexErrors);
+}
+
+export { startup, doLookup, validateOptions };
\ No newline at end of file
diff --git a/src/querying/queryAssetsForAllEntities.js b/src/querying/queryAssetsForAllEntities.js
deleted file mode 100644
index 811dcdf..0000000
--- a/src/querying/queryAssetsForAllEntities.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const { getOr, size, flow, concat, uniqBy } = require('lodash/fp');
-const {
- parseErrorToReadableJSON,
- buildQueryByQueryType
-} = require('../dataTransformations');
-
-const ASSET_QUERY_FIELDS =
- 'id,name,host,createdAt,tags,sourceInfo,activationModules,activationModulesPending,' +
- 'activationModulesNoProfileFound,activationModulesQueuedManifestGen,updatedAt,' +
- 'criticalityScore,isDefaultCriticalityScore,criticalityScoreUpdated,lastVmScanDate,' +
- 'lastComplianceScanDate';
-
-const limit = 200;
-
-const queryAssetsForAllEntities = async (
- entities,
- options,
- requestWithDefaults,
- Logger,
- offset = 0,
- allAssets = []
-) => {
- try {
- const assetQuery = buildQueryByQueryType('assets', entities);
-
- const assetsData = getOr(
- [],
- 'body',
- await requestWithDefaults({
- uri: `${options.url}/portal-front/rest/assetview/1.0/assets`,
- qs: {
- havingQuery: assetQuery,
- fields: ASSET_QUERY_FIELDS,
- order: '-updatedAt',
- includeAssets: true,
- limit,
- offset
- },
- options
- })
- );
-
- const foundAssets = flow(concat(assetsData), uniqBy('id'))(allAssets);
-
- if (size(assetsData) === 200) {
- return await queryAssetsForAllEntities(
- entities,
- options,
- requestWithDefaults,
- Logger,
- offset + limit,
- foundAssets
- );
- }
-
- return foundAssets;
- } catch (error) {
- const err = parseErrorToReadableJSON(error);
- Logger.error(
- {
- detail: 'Failed to Query Assets',
- options,
- formattedError: err
- },
- 'Query Assets Failed'
- );
-
- throw error;
- }
-};
-
-module.exports = queryAssetsForAllEntities;
diff --git a/src/querying/queryAssetsForAllEntities.ts b/src/querying/queryAssetsForAllEntities.ts
new file mode 100644
index 0000000..0adc08d
--- /dev/null
+++ b/src/querying/queryAssetsForAllEntities.ts
@@ -0,0 +1,60 @@
+import { size, flow, concat, uniqBy } from 'lodash/fp';
+import type { Entity, Logger } from '@polarityio/integration-types';
+import type { PolarityRequest } from 'polarity-integration-utils';
+
+import { parseErrorToReadableJSON, buildQueryByQueryType } from '../dataTransformations';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+const ASSET_QUERY_FIELDS = 'id,name,host,createdAt,tags,sourceInfo,activationModules,...';
+const limit = 200;
+
+const queryAssetsForAllEntities = async (
+ entities: Entity[],
+ options: Record,
+ request: PolarityRequest,
+ Logger: Logger,
+ offset = 0,
+ allAssets: any[] = []
+): Promise => {
+ try {
+ const assetQuery = buildQueryByQueryType('assets', entities);
+
+ const response = await request.run({
+ url: `${options.url}/portal-front/rest/assetview/1.0/assets`,
+ qs: {
+ havingQuery: assetQuery,
+ fields: ASSET_QUERY_FIELDS,
+ order: '-updatedAt',
+ includeAssets: true,
+ limit,
+ offset
+ }
+ });
+
+ const assetsData = (response!.body as any[]) || [];
+ const foundAssets = flow(concat(assetsData), uniqBy('id'))(allAssets);
+
+ if (size(assetsData) === 200) {
+ return await queryAssetsForAllEntities(
+ entities,
+ options,
+ request,
+ Logger,
+ offset + limit,
+ foundAssets
+ );
+ }
+
+ return foundAssets;
+ } catch (error) {
+ const err = parseErrorToReadableJSON(error);
+ Logger.error(
+ { detail: 'Failed to Query Assets', url: options.url, formattedError: err },
+ 'Query Assets Failed'
+ );
+ throw error;
+ }
+};
+
+export default queryAssetsForAllEntities;
diff --git a/src/querying/queryHostDetectionListForAllEntities.js b/src/querying/queryHostDetectionListForAllEntities.js
deleted file mode 100644
index 23e9665..0000000
--- a/src/querying/queryHostDetectionListForAllEntities.js
+++ /dev/null
@@ -1,140 +0,0 @@
-const { identity } = require('lodash');
-const {
- get,
- getOr,
- map,
- flow,
- filter,
- eq,
- uniqBy,
- join,
- cond,
- size
-} = require('lodash/fp');
-
-const {
- parseErrorToReadableJSON,
- processResultWithProcessingFormat,
- processPossibleList,
- xmlToJson,
- or
-} = require('../dataTransformations');
-
-const queryHostDetectionListForAllEntities = async (
- entities,
- options,
- requestWithDefaults,
- Logger
-) => {
- const allHostDetectionResultForIpAddresses = await flow(
- filter(flow(get('type'), or(eq('IPv4'), eq('IPv6')))),
- map(get('value')),
- cond([[size, queryHostDetectionList('ips', options, requestWithDefaults, Logger)]])
- )(entities);
-
- const allHostDetectionResultForQids = await flow(
- filter(flow(get('type'), eq('qid'))),
- map(get('value')),
- cond([[size, queryHostDetectionList('qids', options, requestWithDefaults, Logger)]])
- )(entities);
-
- return uniqBy('id', allHostDetectionResultForIpAddresses).concat(
- uniqBy('id', allHostDetectionResultForQids)
- );
-};
-
-const queryHostDetectionList =
- (type, options, requestWithDefaults, Logger) => async (entityValues) => {
- try {
- const responseXml = getOr(
- '',
- 'body',
- await requestWithDefaults({
- method: 'GET',
- url: `${options.url}/api/2.0/fo/asset/host/vm/detection/`,
- qs: {
- action: 'list',
- [type]: join(',', entityValues),
- show_asset_id: 1,
- show_results: 1
- },
- headers: { 'X-Requested-With': 'Polarity' },
- options
- })
- );
-
- const hostDetections = flow(
- get('host_list_vm_detection_output.response.host_list.host'),
- processPossibleList(false)
- )(await xmlToJson(responseXml, Logger));
-
- const processedJson = map(
- processResultWithProcessingFormat(HOST_DETECTIONS_LIST_FORMAT),
- hostDetections
- );
-
- return processedJson;
- } catch (error) {
- const err = parseErrorToReadableJSON(error);
- Logger.error(
- {
- detail: 'Failed to Query Host Detection List',
- formattedError: err
- },
- 'Querying Host Detection List Failed'
- );
-
- throw error;
- }
- };
-
-const HOST_DETECTIONS_LIST_ITEM_FORMAT = {
- qid: 'qid',
- type: 'type',
- severity: 'severity',
- port: 'port',
- protocol: 'protocol',
- ssl: {
- path: 'ssl',
- process: (ssl) => (ssl == 1 ? 'Yes' : 'No')
- },
- results: 'results',
- status: 'status',
- first_found_datetime: 'first_found_datetime',
- last_found_datetime: 'last_found_datetime',
- times_found: 'times_found',
- last_test_datetime: 'last_test_datetime',
- last_update_datetime: 'last_update_datetime',
- is_ignored: {
- path: 'is_ignored',
- process: (is_ignored) => (is_ignored == 1 ? 'Yes' : 'No')
- },
- is_disabled: {
- path: 'is_disabled',
- process: (is_disabled) => (is_disabled == 1 ? 'Yes' : 'No')
- },
- last_processed_datetime: 'last_processed_datetime'
-};
-
-const HOST_DETECTIONS_LIST_FORMAT = {
- id: 'id',
- asset_id: 'asset_id',
- ip: 'ip',
- os: 'os',
- dns: 'dns',
- last_scan_datetime: 'last_scan_datetime',
- last_vm_scanned_date: 'last_vm_scanned_date',
- last_vm_scanned_duration: 'last_vm_scanned_duration',
- category: 'category',
- detection_list: {
- path: 'detection_list',
- process: flow(
- get('detection'),
- processPossibleList(false),
- map(processResultWithProcessingFormat(HOST_DETECTIONS_LIST_ITEM_FORMAT)),
- uniqBy('qid')
- )
- }
-};
-
-module.exports = queryHostDetectionListForAllEntities;
diff --git a/src/querying/queryHostDetectionListForAllEntities.ts b/src/querying/queryHostDetectionListForAllEntities.ts
new file mode 100644
index 0000000..84b3789
--- /dev/null
+++ b/src/querying/queryHostDetectionListForAllEntities.ts
@@ -0,0 +1,132 @@
+import { get, map, flow, filter, eq, uniqBy, join, size } from 'lodash/fp';
+import type { Entity, Logger } from '@polarityio/integration-types';
+import type { PolarityRequest } from 'polarity-integration-utils';
+
+import {
+ parseErrorToReadableJSON,
+ processResultWithProcessingFormat,
+ processPossibleList,
+ xmlToJson,
+ or
+} from '../dataTransformations';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+const queryHostDetectionListForAllEntities = async (
+ entities: Entity[],
+ options: Record,
+ request: PolarityRequest,
+ Logger: Logger
+): Promise => {
+ const ipEntities = filter(flow(get('type'), or(eq('IPv4'), eq('IPv6'))), entities);
+ const ipValues = map(get('value'), ipEntities) as string[];
+
+ const qidEntities = filter(
+ flow(get('type'), (t) => t === 'qid' || t === 'customType'),
+ entities
+ );
+ const qidValues = map(get('value'), qidEntities) as string[];
+
+ const allHostDetectionResultForIpAddresses = size(ipValues)
+ ? await queryHostDetectionList('ips', options, request, Logger)(ipValues)
+ : [];
+
+ const allHostDetectionResultForQids = size(qidValues)
+ ? await queryHostDetectionList('qids', options, request, Logger)(qidValues)
+ : [];
+
+ return uniqBy('id', allHostDetectionResultForIpAddresses).concat(
+ uniqBy('id', allHostDetectionResultForQids)
+ );
+};
+
+const queryHostDetectionList =
+ (type: string, options: Record, request: PolarityRequest, Logger: Logger) =>
+ async (entityValues: string[]): Promise => {
+ try {
+ const response = await request.run({
+ method: 'GET',
+ url: `${options.url}/api/2.0/fo/asset/host/vm/detection/`,
+ qs: {
+ action: 'list',
+ [type]: join(',', entityValues),
+ show_asset_id: 1,
+ show_results: 1
+ },
+ headers: { 'X-Requested-With': 'Polarity' },
+ json: false
+ });
+
+ const responseXml = (response!.body as string) || '';
+
+ const hostDetections = flow(
+ get('host_list_vm_detection_output.response.host_list.host'),
+ processPossibleList(false)
+ )(await xmlToJson(responseXml, Logger));
+
+ const processedJson = map(
+ processResultWithProcessingFormat(HOST_DETECTIONS_LIST_FORMAT),
+ hostDetections
+ );
+
+ return processedJson;
+ } catch (error) {
+ const err = parseErrorToReadableJSON(error);
+ Logger.error(
+ {
+ detail: 'Failed to Query Host Detection List',
+ formattedError: err
+ },
+ 'Querying Host Detection List Failed'
+ );
+ throw error;
+ }
+ };
+
+const HOST_DETECTIONS_LIST_ITEM_FORMAT: Record = {
+ qid: 'qid',
+ type: 'type',
+ severity: 'severity',
+ port: 'port',
+ protocol: 'protocol',
+ ssl: { path: 'ssl', process: (ssl: any) => (ssl == 1 ? 'Yes' : 'No') },
+ results: 'results',
+ status: 'status',
+ first_found_datetime: 'first_found_datetime',
+ last_found_datetime: 'last_found_datetime',
+ times_found: 'times_found',
+ last_test_datetime: 'last_test_datetime',
+ last_update_datetime: 'last_update_datetime',
+ is_ignored: {
+ path: 'is_ignored',
+ process: (is_ignored: any) => (is_ignored == 1 ? 'Yes' : 'No')
+ },
+ is_disabled: {
+ path: 'is_disabled',
+ process: (is_disabled: any) => (is_disabled == 1 ? 'Yes' : 'No')
+ },
+ last_processed_datetime: 'last_processed_datetime'
+};
+
+const HOST_DETECTIONS_LIST_FORMAT: Record = {
+ id: 'id',
+ asset_id: 'asset_id',
+ ip: 'ip',
+ os: 'os',
+ dns: 'dns',
+ last_scan_datetime: 'last_scan_datetime',
+ last_vm_scanned_date: 'last_vm_scanned_date',
+ last_vm_scanned_duration: 'last_vm_scanned_duration',
+ category: 'category',
+ detection_list: {
+ path: 'detection_list',
+ process: flow(
+ get('detection'),
+ processPossibleList(false),
+ map(processResultWithProcessingFormat(HOST_DETECTIONS_LIST_ITEM_FORMAT)),
+ uniqBy('qid')
+ )
+ }
+};
+
+export default queryHostDetectionListForAllEntities;
\ No newline at end of file
diff --git a/src/querying/queryVulnerabilitiesForAllEntities.js b/src/querying/queryVulnerabilitiesForAllEntities.js
deleted file mode 100644
index fd93307..0000000
--- a/src/querying/queryVulnerabilitiesForAllEntities.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const { getOr, size, flow, concat, uniqBy, orderBy } = require('lodash/fp');
-const {
- parseErrorToReadableJSON,
- buildQueryByQueryType
-} = require('../dataTransformations');
-
-const VULNERABILITIES_QUERY_FIELDS =
- 'title,id,qid,title,port,age,typeDetected,assetId,assetName,assetUUID,lastDetected,' +
- 'firstDetected,fqdn,ssl,severity,assetCount,cveids,vulnStatus,ignored,disabled,' +
- 'isQualysPatchable,missingPatchCount,patchLicenseType,patchPlatform';
-
-const limit = 200;
-
-const queryVulnerabilitiesForAllEntities = async (
- entities,
- options,
- requestWithDefaults,
- Logger,
- offset = 0,
- allVulnerabilities = []
-) => {
- try {
- const vulnerabilitiesQuery = buildQueryByQueryType('vulnerabilities', entities);
-
- const vulnerabilitiesData = getOr(
- [],
- 'body',
- await requestWithDefaults({
- uri: `${options.url}/portal-front/rest/assetview/1.0/assets`,
- qs: {
- havingQuery: vulnerabilitiesQuery,
- fields: VULNERABILITIES_QUERY_FIELDS,
- limit,
- offset
- },
- options
- })
- );
-
- const foundVulnerabilities = flow(
- concat(vulnerabilitiesData),
- uniqBy('id')
- )(allVulnerabilities);
-
- if (size(vulnerabilitiesData) === 200) {
- return await queryVulnerabilitiesForAllEntities(
- entities,
- options,
- requestWithDefaults,
- Logger,
- offset + limit,
- foundVulnerabilities
- );
- }
-
- return orderBy('lastDetected.iMillis', 'desc')(foundVulnerabilities);
- } catch (error) {
- const err = parseErrorToReadableJSON(error);
- Logger.error(
- {
- detail: 'Failed to Query Vulnerabilities',
- formattedError: err
- },
- 'Query Vulnerabilities Failed'
- );
-
- throw error;
- }
-};
-
-module.exports = queryVulnerabilitiesForAllEntities;
diff --git a/src/querying/queryVulnerabilitiesForAllEntities.ts b/src/querying/queryVulnerabilitiesForAllEntities.ts
new file mode 100644
index 0000000..f19069e
--- /dev/null
+++ b/src/querying/queryVulnerabilitiesForAllEntities.ts
@@ -0,0 +1,61 @@
+import { size, flow, concat, uniqBy, orderBy } from 'lodash/fp';
+import type { Entity, Logger } from '@polarityio/integration-types';
+import type { PolarityRequest } from 'polarity-integration-utils';
+
+import { parseErrorToReadableJSON, buildQueryByQueryType } from '../dataTransformations';
+
+/* eslint-disable @typescript-eslint/no-explicit-any */
+
+const VULNERABILITIES_QUERY_FIELDS = 'title,id,qid,...';
+const limit = 200;
+
+const queryVulnerabilitiesForAllEntities = async (
+ entities: Entity[],
+ options: Record,
+ request: PolarityRequest,
+ Logger: Logger,
+ offset = 0,
+ allVulnerabilities: any[] = []
+): Promise => {
+ try {
+ const vulnerabilitiesQuery = buildQueryByQueryType('vulnerabilities', entities);
+
+ const response = await request.run({
+ url: `${options.url}/portal-front/rest/assetview/1.0/assets`,
+ qs: {
+ havingQuery: vulnerabilitiesQuery,
+ fields: VULNERABILITIES_QUERY_FIELDS,
+ limit,
+ offset
+ }
+ });
+
+ const vulnerabilitiesData = (response!.body as any[]) || [];
+ const foundVulnerabilities = flow(
+ concat(vulnerabilitiesData),
+ uniqBy('id')
+ )(allVulnerabilities);
+
+ if (size(vulnerabilitiesData) === 200) {
+ return await queryVulnerabilitiesForAllEntities(
+ entities,
+ options,
+ request,
+ Logger,
+ offset + limit,
+ foundVulnerabilities
+ );
+ }
+
+ return orderBy('lastDetected.iMillis', 'desc')(foundVulnerabilities);
+ } catch (error) {
+ const err = parseErrorToReadableJSON(error);
+ Logger.error(
+ { detail: 'Failed to Query Vulnerabilities', formattedError: err },
+ 'Query Vulnerabilities Failed'
+ );
+ throw error;
+ }
+};
+
+export default queryVulnerabilitiesForAllEntities;
diff --git a/src/validateOptions.js b/src/validateOptions.js
deleted file mode 100644
index 9eeb158..0000000
--- a/src/validateOptions.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const fp = require('lodash/fp');
-const reduce = require('lodash/fp/reduce').convert({ cap: false });
-
-
-const validateStringOptions = (stringOptionsErrorMessages, options, otherErrors = []) =>
- reduce((agg, message, optionName) => {
- const isString = typeof options[optionName].value === 'string';
- const isEmptyString = isString && fp.isEmpty(options[optionName].value);
-
- return !isString || isEmptyString
- ? agg.concat({
- key: optionName,
- message
- })
- : agg;
- }, otherErrors)(stringOptionsErrorMessages);
-
-const validateUrlOption = (url, otherErrors = []) => {
- const endWithError =
- url && url.endsWith('/')
- ? otherErrors.concat({
- key: 'url',
- message:
- 'Your URL must not end with a /'
- })
- : otherErrors;
- if (endWithError.length) return endWithError;
-
- if (url) {
- try {
- new URL(url);
- } catch (_) {
- return otherErrors.concat({
- key: 'url',
- message:
- 'This URL is invalid. You must provide a valid URL.'
- });
- }
- }
-
- return otherErrors;
-};
-
-
-module.exports = { validateStringOptions, validateUrlOption };
diff --git a/src/validateOptions.ts b/src/validateOptions.ts
new file mode 100644
index 0000000..f2052f1
--- /dev/null
+++ b/src/validateOptions.ts
@@ -0,0 +1,63 @@
+import fp from 'lodash/fp';
+import reduce from 'lodash/fp/reduce';
+import type { ValidationError, ValidateOptionsUserOptions } from '@polarityio/integration-types';
+
+const uncappedReduce = (reduce as any).convert({ cap: false });
+
+export const validateStringOptions = (
+ stringOptionsErrorMessages: Record,
+ options: ValidateOptionsUserOptions,
+ otherErrors: ValidationError[] = []
+): ValidationError[] =>
+ uncappedReduce((agg: ValidationError[], message: string, optionName: string) => {
+ const isString = typeof options[optionName].value === 'string';
+ const isEmptyString = isString && fp.isEmpty(options[optionName].value as string);
+
+ return !isString || isEmptyString ? agg.concat({ key: optionName, message }) : agg;
+ }, otherErrors)(stringOptionsErrorMessages);
+
+export const validateUrlOption = (
+ url: string,
+ otherErrors: ValidationError[] = []
+): ValidationError[] => {
+ const endWithError =
+ url && url.endsWith('/')
+ ? otherErrors.concat({
+ key: 'url',
+ message: 'Your URL must not end with a /'
+ })
+ : otherErrors;
+
+ if (endWithError.length) return endWithError;
+
+ if (url) {
+ try {
+ new URL(url);
+ } catch {
+ return otherErrors.concat({
+ key: 'url',
+ message: 'This URL is invalid. You must provide a valid URL.'
+ });
+ }
+ }
+
+ return otherErrors;
+};
+
+export const validateCustomTypeValueRegex = (
+ options: ValidateOptionsUserOptions,
+ otherErrors: ValidationError[] = []
+): ValidationError[] => {
+ const regexValue = options.customTypeValueRegex?.value as string | undefined;
+ if (regexValue) {
+ try {
+ new RegExp(regexValue);
+ } catch {
+ return otherErrors.concat({
+ key: 'customTypeValueRegex',
+ message: 'Invalid regular expression syntax.'
+ });
+ }
+ }
+ return otherErrors;
+};
\ No newline at end of file
diff --git a/styles/styles.less b/styles/styles.less
deleted file mode 100644
index 38d0270..0000000
--- a/styles/styles.less
+++ /dev/null
@@ -1,112 +0,0 @@
-.block {
- margin-bottom: 5px;
-}
-
-hr {
- display: block;
- margin-top: 0.5em;
- margin-bottom: 0.5em;
- margin-left: auto;
- margin-right: auto;
- border-style: inset;
- border-width: 1px;
-}
-
-.expandable-title {
- display: block;
- color: #5ccd18 !important;
- font-weight: 600;
- line-height: 16px;
- margin-bottom: 5px;
- .text {
- color: #5ccd18 !important;
- border-bottom: 1px solid #5ccd18;
- .desc {
- color: black !important;
- font-weight: 400 !important;
- }
- }
-}
-
-.p-title {
- font-size: 14px !important;
- font-weight: 500;
- text-decoration: underline;
-}
-
-hr {
- margin-top: 13px;
-}
-
-.load-more {
- margin-top: 10px;
- font-size: 14px;
- color: darkgray !important;
- &:hover {
- color: rgb(119, 119, 119) !important;
- }
-}
-
-.loading {
- font-size: 14px;
- margin-top: 10px;
- color: darkgray !important;
-}
-
-.no-style-button {
- cursor: pointer;
- font-size: 100%;
- font-family: inherit;
- border: 0;
- padding: 0;
- background-color: transparent;
-
- &:hover,
- &:focus {
- background: inherit;
- }
-
- &:focus {
- outline: none;
- }
-
- &:active {
- transform: none;
- }
-}
-
-.copy-button {
- width: 15px;
- border-radius: 3px;
- &:hover,
- &:focus {
- background: inherit;
- background-color: rgba(153, 153, 153, 0.2);
- border-color: rgba(153, 153, 153, 0.2);
- cursor: pointer;
- }
-
- &:focus {
- outline: none;
- }
-
- &:active {
- cursor: pointer;
- .header-button-icon {
- color: #fff;
- }
- background-color: rgba(100, 100, 100, 0.4);;
- border-color: rgba(100, 100, 100, 0.4);;
- transform: none;
- }
-}
-
-.copied-label {
- color: lightgray;
-}
-
-
-
-.operation-button-icon {
- color: #9e9e9e;
-}
diff --git a/templates/block.hbs b/templates/block.hbs
deleted file mode 100644
index f30ead5..0000000
--- a/templates/block.hbs
+++ /dev/null
@@ -1,274 +0,0 @@
-
-{{#each tabKeys as |tabKey|}}
- {{#if (eq activeTab tabKey)}}
- {{#each (get details tabKey) as |displayField displayFieldIndex|}}
- {{#if displayField.isTitle}}
- {{#if (and displayField.displayLink (or displayField.value displayField.label))}}
-
- {{else if displayField.showLabelAndValue}}
-
- {{#if displayField.displayLink}}
-
- {{displayField.label}}: {{displayField.value}}
-
- {{else}}
- {{displayField.label}}: {{displayField.value}}
- {{/if}}
- {{#if
- (and
- displayField.pathIsLinkToMoreData (not displayField.moreDataIsPopulated)
- )
- }}
- {{fa-icon "spinner-third" fixedWidth=true spin=true}}
- {{/if}}
-
- {{else}}
-
- {{#if displayField.displayLink}}
-
- {{or displayField.label displayField.value}}
-
- {{else}}
- {{or displayField.label displayField.value}}
- {{/if}}
- {{#if
- (and
- displayField.pathIsLinkToMoreData (not displayField.moreDataIsPopulated)
- )
- }}
- {{fa-icon "spinner-third" fixedWidth=true spin=true}}
- {{/if}}
-
- {{/if}}
- {{else if displayField.isTextBlock}}
-
- {{#if displayField.capitalize}}
- {{capitalize displayField.value}}
- {{else}}
- {{displayField.value}}
- {{/if}}
-
- {{else if displayField.isListOfLinks}}
-
- {{else if displayField.isHtml}}
-
- {{else if displayField.isList}}
-
- {{displayField.label}}
-
-
- {{#each displayField.value as |itemDisplayFields itemDisplayFieldsIndex|}}
- {{#if displayField.collapsibleListItems}}
- {{#if (get expandableTitleStates (concat displayFieldIndex itemDisplayFieldsIndex displayField.label))}}
-
- {{itemDisplayFields.0.value}} {{fa-icon "angle-up"}}
-
- {{#each itemDisplayFields as |itemDisplayField itemDisplayFieldIndex|}}
- {{#if (not (eq itemDisplayFieldIndex 0))}}
-
- {{itemDisplayField.label}}:
-
- {{#if itemDisplayField.isDate}}
- {{moment-format
- itemDisplayField.value
- "MM/DD/YYYY HH:mm:ss"
- timeZone=timezone
- }}
- {{else}}
- {{itemDisplayField.value}}
- {{/if}}
-
- {{#if itemDisplayField.fieldIsCopyable}}
-
- {{fa-icon
- "copy"
- fixedWidth=true
- size="md"
- class="operation-button-icon"
- }}
-
- {{#if (get copiedStates (concat displayFieldIndex itemDisplayField.label itemDisplayFieldIndex))}}
- Copied
- {{/if}}
- {{/if}}
-
- {{/if}}
- {{/each}}
- {{else}}
-
- {{itemDisplayFields.0.value}} {{fa-icon "angle-down"}}
-
- {{/if}}
- {{else}}
- {{#each itemDisplayFields as |itemDisplayField itemDisplayFieldIndex|}}
-
- {{itemDisplayField.label}}:
-
- {{#if itemDisplayField.isDate}}
- {{moment-format
- itemDisplayField.value
- "MM/DD/YYYY HH:mm:ss"
- timeZone=timezone
- }}
- {{else}}
- {{itemDisplayField.value}}
- {{/if}}
-
- {{#if itemDisplayField.fieldIsCopyable}}
-
- {{fa-icon
- "copy"
- fixedWidth=true
- size="md"
- class="operation-button-icon"
- }}
-
- {{#if (get copiedStates (concat displayFieldIndex itemDisplayField.label itemDisplayFieldIndex))}}
- Copied
- {{/if}}
- {{/if}}
-
- {{/each}}
- {{/if}}
- {{/each}}
-
- {{else if displayField.isNewSectionLineBreak}}
-
- {{else if displayField.fieldIsCopyable}}
-
- {{displayField.label}}:
-
- {{#if displayField.isDate}}
- {{moment-format
- displayField.value
- "MM/DD/YYYY HH:mm:ss"
- timeZone=timezone
- }}
- {{else if displayField.capitalize}}
- {{capitalize displayField.value}}
- {{else}}
- {{displayField.value}}
- {{/if}}
-
-
- {{fa-icon
- "copy"
- fixedWidth=true
- size="md"
- class="operation-button-icon"
- }}
-
- {{#if (get copiedStates (concat displayFieldIndex displayField.label 0))}}
- Copied
- {{/if}}
-
- {{else}}
-
- {{/if}}
- {{/each}}
- {{/if}}
-{{/each}}
\ No newline at end of file
diff --git a/test/integration.test.ts b/test/integration.test.ts
new file mode 100644
index 0000000..0c813ef
--- /dev/null
+++ b/test/integration.test.ts
@@ -0,0 +1,465 @@
+import { vi, describe, it, expect, beforeEach } from 'vitest';
+import type {
+ Entity,
+ DoLookupUserOptions,
+ IntegrationContext
+} from '@polarityio/integration-types';
+import type { HttpRequestResponse } from 'polarity-integration-utils';
+
+function createEntity(type: string, value: string): Entity {
+ const isDomain = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.test(value);
+ const isIPv4 = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/.test(value);
+ const isIPv6 = /^[\da-fA-F:]+$/.test(value) && value.includes(':');
+ const typeId = type === 'IP' ? 'IPv4' : type.startsWith('custom.') ? 'custom' : type;
+ return {
+ value,
+ rawValue: value,
+ displayValue: value,
+ type: typeId,
+ types: [type],
+ isDomain,
+ isIPv4,
+ isIP: isIPv4 || isIPv6,
+ isIPv6,
+ isEmail: false,
+ isHash: false,
+ isHex: false,
+ isHTMLTag: false,
+ isMD5: false,
+ isPrivateIP: false,
+ isSHA1: false,
+ isSHA256: false,
+ isSHA512: false,
+ isURL: false,
+ channels: [],
+ requestContext: { requestType: 'OnDemand', isUserInitiated: true }
+ } as unknown as Entity;
+}
+
+function createMockIntegrationContext() {
+ const createCacheScope = () => ({ get: vi.fn(), set: vi.fn(), delete: vi.fn() });
+ const logger = {
+ child: vi.fn().mockReturnThis(),
+ info: vi.fn(),
+ debug: vi.fn(),
+ trace: vi.fn(),
+ warn: vi.fn(),
+ error: vi.fn(),
+ fatal: vi.fn()
+ };
+ (logger.child as any).mockReturnValue(logger);
+ return {
+ cache: {
+ global: createCacheScope(),
+ integration: createCacheScope(),
+ user: createCacheScope()
+ },
+ integrationId: 'test-integration',
+ userId: 1,
+ logger,
+ startPolling: vi.fn(),
+ stopPolling: vi.fn()
+ };
+}
+
+const { mockRun, mockSetLogger } = vi.hoisted(() => ({
+ mockRun: vi.fn(),
+ mockSetLogger: vi.fn()
+}));
+
+vi.mock('polarity-integration-utils', () => {
+ class MockIntegrationError extends Error {
+ cause: unknown;
+ meta: unknown;
+ constructor(message: string, props?: any) {
+ super(message);
+ this.name = 'IntegrationError';
+ this.cause = props?.cause;
+ this.meta = props?.meta;
+ }
+ }
+
+ class MockPolarityRequest {
+ run = mockRun;
+ runInParallel = vi.fn();
+ userOptions: any = null;
+ network: any = null;
+ limiter: any = null;
+ hooks = { beforeRequest: [], afterResponse: [], onApiError: [], onNetworkError: [] };
+ constructor(_opts?: any) {}
+ }
+
+ return {
+ PolarityRequest: MockPolarityRequest,
+ setLogger: mockSetLogger,
+ IntegrationError: MockIntegrationError,
+ ApiRequestError: class extends Error {
+ constructor(m: string) {
+ super(m);
+ this.name = 'ApiRequestError';
+ }
+ },
+ NetworkError: class extends Error {
+ constructor(m: string) {
+ super(m);
+ this.name = 'NetworkError';
+ }
+ }
+ };
+});
+
+import { doLookup, startup, validateOptions } from '../src/integration';
+
+const createMockContext = () => createMockIntegrationContext();
+
+const createOptions = (overrides: Partial> = {}): DoLookupUserOptions =>
+ ({
+ url: 'https://qualysapi.qualys.com',
+ username: 'testuser',
+ password: 'testpass',
+ ...overrides
+ }) as unknown as DoLookupUserOptions;
+
+const HOST_DETECTION_XML = `
+
+
+
+
+ 12345
+ 67890
+ 192.168.1.1
+ Linux 4.15
+ host.example.com
+ 2024-01-15T10:30:00Z
+ 2024-01-15T10:30:00Z
+ 120
+ Confirmed
+
+
+ 38623
+ Confirmed
+ 3
+ 443
+ tcp
+ 1
+ SSL Certificate - Subject
+ Active
+ 2024-01-10T08:00:00Z
+ 2024-01-15T10:30:00Z
+ 5
+ 2024-01-15T10:30:00Z
+ 2024-01-15T10:30:00Z
+ 0
+ 0
+ 2024-01-15T10:30:00Z
+
+
+
+
+
+ `;
+
+const EMPTY_HOST_DETECTION_XML = `
+
+
+
+ `;
+
+describe('Qualys Integration', () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ describe('startup', () => {
+ it('should initialize without error', () => {
+ const mockLogger = {
+ info: vi.fn(),
+ debug: vi.fn(),
+ trace: vi.fn(),
+ warn: vi.fn(),
+ error: vi.fn(),
+ fatal: vi.fn(),
+ child: vi.fn()
+ };
+ expect(() => startup(mockLogger as any)).not.toThrow();
+ });
+ });
+
+ describe('doLookup', () => {
+ beforeEach(() => {
+ const mockLogger = {
+ info: vi.fn(),
+ debug: vi.fn(),
+ trace: vi.fn(),
+ warn: vi.fn(),
+ error: vi.fn(),
+ fatal: vi.fn(),
+ child: vi.fn()
+ };
+ startup(mockLogger as any);
+ });
+
+ it('should return lookup results with data for an IPv4 entity with host detections', async () => {
+ mockRun.mockResolvedValue({
+ statusCode: 200,
+ body: HOST_DETECTION_XML,
+ headers: {}
+ } as HttpRequestResponse);
+
+ const entities: Entity[] = [createEntity('IPv4', '192.168.1.1')];
+ const options = createOptions();
+ const context = createMockContext();
+
+ const results = await doLookup(entities, options, context as unknown as IntegrationContext);
+
+ expect(results).toHaveLength(1);
+ expect(results![0].entity.value).toBe('192.168.1.1');
+ expect(results![0].data).not.toBeNull();
+ expect(results![0].data!.summary).toContain('Host Detections: 1');
+ expect(results![0].data!.details).toHaveProperty('tabKeys');
+ });
+
+ it('should return data: null for an entity with no results', async () => {
+ mockRun.mockResolvedValue({
+ statusCode: 200,
+ body: EMPTY_HOST_DETECTION_XML,
+ headers: {}
+ } as HttpRequestResponse);
+
+ const entities: Entity[] = [createEntity('IPv4', '10.0.0.1')];
+ const options = createOptions();
+ const context = createMockContext();
+
+ const results = await doLookup(entities, options, context as unknown as IntegrationContext);
+
+ expect(results).toHaveLength(1);
+ expect(results![0].data).toBeNull();
+ });
+
+ it('should handle multiple entities', async () => {
+ mockRun.mockResolvedValue({
+ statusCode: 200,
+ body: EMPTY_HOST_DETECTION_XML,
+ headers: {}
+ } as HttpRequestResponse);
+
+ const entities: Entity[] = [
+ createEntity('IPv4', '192.168.1.1'),
+ createEntity('IPv4', '192.168.1.2')
+ ];
+ const options = createOptions();
+ const context = createMockContext();
+
+ const results = await doLookup(entities, options, context as unknown as IntegrationContext);
+
+ expect(results).toHaveLength(2);
+ });
+
+ it('should return data: null for ignored IPs (127.0.0.1)', async () => {
+ mockRun.mockResolvedValue({
+ statusCode: 200,
+ body: EMPTY_HOST_DETECTION_XML,
+ headers: {}
+ } as HttpRequestResponse);
+
+ const entities: Entity[] = [createEntity('IPv4', '127.0.0.1')];
+ const options = createOptions();
+ const context = createMockContext();
+
+ const results = await doLookup(entities, options, context as unknown as IntegrationContext);
+
+ expect(results).toHaveLength(1);
+ expect(results![0].data).toBeNull();
+ });
+
+ it('should pass correct request options to the API', async () => {
+ mockRun.mockResolvedValue({
+ statusCode: 200,
+ body: EMPTY_HOST_DETECTION_XML,
+ headers: {}
+ } as HttpRequestResponse);
+
+ const entities: Entity[] = [createEntity('IPv4', '10.20.30.40')];
+ const options = createOptions({ url: 'https://qualysapi.example.com' });
+ const context = createMockContext();
+
+ await doLookup(entities, options, context as unknown as IntegrationContext);
+
+ expect(mockRun).toHaveBeenCalledWith(
+ expect.objectContaining({
+ method: 'GET',
+ url: 'https://qualysapi.example.com/api/2.0/fo/asset/host/vm/detection/',
+ qs: expect.objectContaining({
+ action: 'list',
+ ips: '10.20.30.40',
+ show_asset_id: 1,
+ show_results: 1
+ }),
+ headers: { 'X-Requested-With': 'Polarity' },
+ json: false
+ })
+ );
+ });
+
+ it('should throw IntegrationError when API request fails', async () => {
+ const apiError = new Error('API request failed');
+ mockRun.mockRejectedValue(apiError);
+
+ const entities: Entity[] = [createEntity('IPv4', '192.168.1.1')];
+ const options = createOptions();
+ const context = createMockContext();
+
+ await expect(
+ doLookup(entities, options, context as unknown as IntegrationContext)
+ ).rejects.toThrow('API request failed');
+ });
+
+ it('should throw IntegrationError with default message for non-Error objects', async () => {
+ mockRun.mockRejectedValue('string error');
+
+ const entities: Entity[] = [createEntity('IPv4', '192.168.1.1')];
+ const options = createOptions();
+ const context = createMockContext();
+
+ await expect(
+ doLookup(entities, options, context as unknown as IntegrationContext)
+ ).rejects.toThrow('Searching Failed');
+ });
+
+ it('should not make API calls when only ignored IPs are provided', async () => {
+ const entities: Entity[] = [
+ createEntity('IPv4', '127.0.0.1'),
+ createEntity('IPv4', '255.255.255.255'),
+ createEntity('IPv4', '0.0.0.0')
+ ];
+ const options = createOptions();
+ const context = createMockContext();
+
+ const results = await doLookup(entities, options, context as unknown as IntegrationContext);
+
+ expect(mockRun).not.toHaveBeenCalled();
+ expect(results).toHaveLength(3);
+ results!.forEach((r) => expect(r.data).toBeNull());
+ });
+
+ it('should handle QID custom type entities', async () => {
+ mockRun.mockResolvedValue({
+ statusCode: 200,
+ body: HOST_DETECTION_XML,
+ headers: {}
+ } as HttpRequestResponse);
+
+ const entity = createEntity('custom', 'QID: 38623') as any;
+ entity.type = 'custom';
+ entity.types = ['custom.qid'];
+ const entities: Entity[] = [entity];
+ const options = createOptions();
+ const context = createMockContext();
+
+ const results = await doLookup(entities, options, context as unknown as IntegrationContext);
+
+ expect(results).toHaveLength(1);
+ expect(mockRun).toHaveBeenCalledWith(
+ expect.objectContaining({
+ qs: expect.objectContaining({
+ qids: '38623'
+ })
+ })
+ );
+ });
+ });
+
+ describe('validateOptions', () => {
+ it('should return no errors when all options are valid', () => {
+ const options = {
+ url: { value: 'https://qualysapi.qualys.com' },
+ username: { value: 'testuser' },
+ password: { value: 'testpass' }
+ };
+ const context = createMockContext();
+
+ const errors = validateOptions(options as any, context as unknown as IntegrationContext);
+
+ expect(errors).toHaveLength(0);
+ });
+
+ it('should return error when url is empty', () => {
+ const options = {
+ url: { value: '' },
+ username: { value: 'testuser' },
+ password: { value: 'testpass' }
+ };
+ const context = createMockContext();
+
+ const errors = validateOptions(options as any, context as unknown as IntegrationContext);
+
+ expect(errors.length).toBeGreaterThan(0);
+ expect(errors.some((e) => e.key === 'url')).toBe(true);
+ });
+
+ it('should return error when username is empty', () => {
+ const options = {
+ url: { value: 'https://qualysapi.qualys.com' },
+ username: { value: '' },
+ password: { value: 'testpass' }
+ };
+ const context = createMockContext();
+
+ const errors = validateOptions(options as any, context as unknown as IntegrationContext);
+
+ expect(errors.some((e) => e.key === 'username')).toBe(true);
+ });
+
+ it('should return error when password is empty', () => {
+ const options = {
+ url: { value: 'https://qualysapi.qualys.com' },
+ username: { value: 'testuser' },
+ password: { value: '' }
+ };
+ const context = createMockContext();
+
+ const errors = validateOptions(options as any, context as unknown as IntegrationContext);
+
+ expect(errors.some((e) => e.key === 'password')).toBe(true);
+ });
+
+ it('should return error when URL ends with a slash', () => {
+ const options = {
+ url: { value: 'https://qualysapi.qualys.com/' },
+ username: { value: 'testuser' },
+ password: { value: 'testpass' }
+ };
+ const context = createMockContext();
+
+ const errors = validateOptions(options as any, context as unknown as IntegrationContext);
+
+ expect(errors.some((e) => e.key === 'url' && e.message.includes('/'))).toBe(true);
+ });
+
+ it('should return error when URL is invalid', () => {
+ const options = {
+ url: { value: 'not-a-valid-url' },
+ username: { value: 'testuser' },
+ password: { value: 'testpass' }
+ };
+ const context = createMockContext();
+
+ const errors = validateOptions(options as any, context as unknown as IntegrationContext);
+
+ expect(errors.some((e) => e.key === 'url' && e.message.includes('invalid'))).toBe(true);
+ });
+
+ it('should return multiple errors when multiple fields are invalid', () => {
+ const options = {
+ url: { value: '' },
+ username: { value: '' },
+ password: { value: '' }
+ };
+ const context = createMockContext();
+
+ const errors = validateOptions(options as any, context as unknown as IntegrationContext);
+
+ expect(errors.length).toBeGreaterThanOrEqual(3);
+ });
+ });
+});
diff --git a/test/web-components/details.test.ts b/test/web-components/details.test.ts
new file mode 100644
index 0000000..7600b8b
--- /dev/null
+++ b/test/web-components/details.test.ts
@@ -0,0 +1,319 @@
+import { describe, it, expect, beforeEach, afterEach } from 'vitest';
+import { DetailsComponent } from '../../web-components/details';
+import type { IBlock } from '@polarityio/pi-components';
+
+customElements.define('test-qualys-details', DetailsComponent);
+
+function createBlock(details: Record): IBlock {
+ return {
+ integrationId: 'qualys-integration',
+ acronym: 'QLS',
+ data: { details, summary: ['Host Detections: 1'] }
+ };
+}
+
+async function renderComponent(block: IBlock): Promise {
+ const el = document.createElement('test-qualys-details') as DetailsComponent;
+ (el as any).services = {
+ currentServer: {},
+ currentUser: {},
+ flashMessages: {},
+ moment: {},
+ notificationsData: {},
+ polarityx: {},
+ searchData: {},
+ session: {},
+ store: {},
+ windowService: {},
+ log: {},
+ integrationMessenger: {},
+ lookupService: () => undefined
+ };
+ el.block = block;
+ document.body.appendChild(el);
+ await el.updateComplete;
+ return el;
+}
+
+function getShadowHTML(el: DetailsComponent): string {
+ return el.shadowRoot?.innerHTML || '';
+}
+
+describe('Qualys DetailsComponent', () => {
+ let el: DetailsComponent | null = null;
+
+ afterEach(() => {
+ if (el && el.parentNode) {
+ el.parentNode.removeChild(el);
+ }
+ el = null;
+ });
+
+ it('should render without errors when given valid host detection data', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ { label: 'IP Address', value: '192.168.1.1', isTitle: true, showLabelAndValue: true },
+ { label: 'Host Detection ID', value: '12345' },
+ { label: 'Asset Id', value: '67890' },
+ { label: 'Operating System', value: 'Linux 4.15' }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('192.168.1.1');
+ expect(html).toContain('IP Address');
+ });
+
+ it('should render nothing when tabKeys is empty', async () => {
+ el = await renderComponent(createBlock({ tabKeys: [] }));
+ const html = getShadowHTML(el);
+ expect(html).not.toContain('pi-tab');
+ expect(html).not.toContain('pi-key-value');
+ });
+
+ it('should render nothing when details is undefined', async () => {
+ const block: IBlock = {
+ integrationId: 'qualys-integration',
+ acronym: 'QLS',
+ data: { details: undefined as any, summary: [] }
+ };
+ el = await renderComponent(block);
+ const html = getShadowHTML(el);
+ expect(html).not.toContain('pi-key-value');
+ });
+
+ it('should render key-value pairs for standard fields', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ { label: 'Operating System', value: 'Linux 4.15' },
+ { label: 'DNS', value: 'host.example.com' },
+ { label: 'Category', value: 'Confirmed' }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('Linux 4.15');
+ expect(html).toContain('host.example.com');
+ expect(html).toContain('Confirmed');
+ });
+
+ it('should render title fields with showLabelAndValue', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ { label: 'IP Address', value: '10.0.0.1', isTitle: true, showLabelAndValue: true }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('IP Address');
+ expect(html).toContain('10.0.0.1');
+ expect(html).toContain(' {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [{ label: 'Last Scanned', value: '2024-01-15T10:30:00Z', isDate: true }]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('Last Scanned');
+ // Should contain a formatted date (not the raw ISO string)
+ expect(html).toContain('01/15/2024');
+ });
+
+ it('should render collapsible list items for detection lists', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ {
+ label: 'Detections List',
+ isList: true,
+ collapsibleListItems: true,
+ indent: 1,
+ value: [
+ [
+ { label: 'Detection Result', value: 'SSL Certificate' },
+ { label: 'QID', value: '38623', fieldIsCopyable: true, shouldCopyFieldLabel: true },
+ { label: 'Severity', value: '3' }
+ ]
+ ]
+ }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('Detections List');
+ expect(html).toContain('SSL Certificate');
+ // Collapsed by default — inner fields should not be visible
+ expect(html).not.toContain('Severity');
+ });
+
+ it('should render HTML content in expandable sections', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ {
+ label: 'Diagnosis',
+ value: ' This is a vulnerability description
',
+ isHtml: true
+ }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('Diagnosis');
+ // HTML content is collapsed by default
+ expect(html).not.toContain('This is a vulnerability description');
+ });
+
+ it('should render the copy button', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [{ label: 'IP', value: '192.168.1.1' }]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('pi-copy-button');
+ });
+
+ it('should render section breaks for isNewSectionLineBreak fields', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ { label: 'Field1', value: 'value1' },
+ { isNewSectionLineBreak: true },
+ { label: 'Field2', value: 'value2' }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('section-break');
+ });
+
+ it('should not render tabs when there is only one visible tab', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [{ label: 'Field', value: 'value' }]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).not.toContain('pi-tab-group');
+ });
+
+ it('should render tabs when there are multiple visible tabs', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections', 'knowledgeBase'],
+ hostDetections: [{ label: 'IP', value: '192.168.1.1' }],
+ knowledgeBase: [{ label: 'Title', value: 'Vuln Title', isTitle: true }]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('pi-tab-group');
+ expect(html).toContain('Host Detections');
+ expect(html).toContain('Knowledge Base');
+ });
+
+ it('should skip tabs with empty data arrays', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections', 'emptyTab'],
+ hostDetections: [{ label: 'IP', value: '192.168.1.1' }],
+ emptyTab: []
+ })
+ );
+
+ const html = getShadowHTML(el);
+ // Should NOT show a tab group since only one tab has data
+ expect(html).not.toContain('pi-tab-group');
+ });
+
+ it('should render copyable fields with copy button', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ { label: 'QID', value: '38623', fieldIsCopyable: true, shouldCopyFieldLabel: true }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('copyable-field');
+ expect(html).toContain('38623');
+ expect(html).toContain('QID');
+ });
+
+ it('should render links with pi-external-link for title fields with displayLink', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ {
+ label: 'Host',
+ value: 'server1',
+ isTitle: true,
+ displayLink: 'https://example.com/host/1'
+ }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('pi-external-link');
+ expect(html).toContain('https://example.com/host/1');
+ });
+
+ it('should render list of links', async () => {
+ el = await renderComponent(
+ createBlock({
+ tabKeys: ['hostDetections'],
+ hostDetections: [
+ {
+ label: 'CVE IDs',
+ isListOfLinks: true,
+ value: [
+ {
+ url: 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-0001',
+ id: 'CVE-2024-0001'
+ },
+ {
+ url: 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-0002',
+ id: 'CVE-2024-0002'
+ }
+ ]
+ }
+ ]
+ })
+ );
+
+ const html = getShadowHTML(el);
+ expect(html).toContain('CVE IDs');
+ expect(html).toContain('CVE-2024-0001');
+ expect(html).toContain('CVE-2024-0002');
+ expect(html).toContain('pi-external-link');
+ });
+});
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..7bee2dc
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "CommonJS",
+ "moduleResolution": "node",
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "declaration": true,
+ "sourceMap": true,
+ "experimentalDecorators": true,
+ "useDefineForClassFields": false
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": ["node_modules", "dist", "web-components"]
+}
diff --git a/tsconfig.web.json b/tsconfig.web.json
new file mode 100644
index 0000000..ce44f5f
--- /dev/null
+++ b/tsconfig.web.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "experimentalDecorators": true,
+ "useDefineForClassFields": false,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "noEmit": true
+ },
+ "include": ["web-components/**/*.ts"]
+}
diff --git a/vite.config.js b/vite.config.js
new file mode 100644
index 0000000..1d275b4
--- /dev/null
+++ b/vite.config.js
@@ -0,0 +1,36 @@
+import config from './config/config.json' with { type: 'json' };
+import { defineConfig } from 'vite';
+import { transformComponentNames, VIRTUAL_COMPONENTS_ID } from '@polarityio/vite-plugin-icl';
+import { resolve } from 'node:path';
+
+export default defineConfig({
+ plugins: [
+ transformComponentNames({
+ componentsDir: resolve(__dirname, 'web-components'),
+ componentRegistries: [
+ '@polarityio/pi-components/component-registry.json',
+ ],
+ }),
+ ],
+ build: {
+ outDir: 'dist',
+ emptyOutDir: false,
+ lib: {
+ entry: VIRTUAL_COMPONENTS_ID,
+ name: 'qualys-v2_build',
+ fileName: () => {
+ const webComponentsConfig = config.webComponents;
+ return webComponentsConfig.moduleFilename;
+ },
+ formats: ['es'],
+ },
+ minify: false,
+ rollupOptions: {
+ output: {
+ globals: {
+ lit: 'lit',
+ },
+ },
+ },
+ },
+});
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 0000000..e6cf8f6
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,54 @@
+import { defineConfig } from 'vitest/config';
+import { playwright } from '@vitest/browser-playwright';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+const resolveConfig = {
+ alias: [
+ {
+ find: /^polarity-integration-utils\/requests$/,
+ replacement: path.resolve(
+ __dirname,
+ 'node_modules/polarity-integration-utils/dist/lib/requests/index.js'
+ )
+ },
+ {
+ find: /^polarity-integration-utils$/,
+ replacement: path.resolve(
+ __dirname,
+ 'node_modules/polarity-integration-utils/dist/lib/index.js'
+ )
+ }
+ ]
+};
+
+export default defineConfig({
+ resolve: resolveConfig,
+ test: {
+ projects: [
+ {
+ resolve: resolveConfig,
+ test: {
+ name: 'server',
+ environment: 'node',
+ include: ['test/**/*.test.ts'],
+ exclude: ['test/web-components/**']
+ }
+ },
+ {
+ resolve: resolveConfig,
+ test: {
+ name: 'browser',
+ include: ['test/web-components/**/*.test.ts'],
+ browser: {
+ enabled: true,
+ provider: playwright(),
+ instances: [{ browser: 'chromium' }]
+ }
+ }
+ }
+ ]
+ }
+});
diff --git a/web-components/details.ts b/web-components/details.ts
new file mode 100644
index 0000000..63938c5
--- /dev/null
+++ b/web-components/details.ts
@@ -0,0 +1,628 @@
+import { css, html, nothing, unsafeCSS } from 'lit';
+import { property, state } from 'lit/decorators.js';
+import { unsafeHTML } from 'lit/directives/unsafe-html.js';
+import { IntegrationComponentBase, IBlock, typographyCSS } from '@polarityio/pi-components';
+import { faAngleUp, faAngleDown, faCopy } from '@polarityio/pi-icon';
+
+interface DisplayField {
+ label?: string;
+ value?: any;
+ isTitle?: boolean;
+ isDate?: boolean;
+ isList?: boolean;
+ isListOfLinks?: boolean;
+ isHtml?: boolean;
+ isTextBlock?: boolean;
+ isNewSectionLineBreak?: boolean;
+ indent?: number;
+ collapsibleListItems?: boolean;
+ showLabelAndValue?: boolean;
+ fieldIsCopyable?: boolean;
+ shouldCopyFieldLabel?: boolean;
+ displayLink?: string;
+ icon?: string;
+ capitalize?: boolean;
+}
+
+interface Details {
+ tabKeys: string[];
+ [key: string]: DisplayField[] | string[] | any;
+}
+
+/**
+ * Converts a camelCase or PascalCase key like "hostDetections"
+ * to a title-cased, spaced label like "Host Detections".
+ */
+function humanizeTabKey(key: string): string {
+ return key
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
+ .replace(/^./, (c) => c.toUpperCase());
+}
+
+/**
+ * Formats an ISO 8601 date string using Intl.DateTimeFormat (Chrome 90 safe).
+ */
+function formatDate(value: string): string {
+ try {
+ const date = new Date(value);
+ if (isNaN(date.getTime())) return value;
+ const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
+ return new Intl.DateTimeFormat('en-US', {
+ month: '2-digit',
+ day: '2-digit',
+ year: 'numeric',
+ hour: '2-digit',
+ minute: '2-digit',
+ second: '2-digit',
+ hour12: false,
+ timeZone: tz
+ }).format(date);
+ } catch {
+ return String(value);
+ }
+}
+
+function capitalizeStr(str: string): string {
+ if (!str) return '';
+ return str.charAt(0).toUpperCase() + str.slice(1);
+}
+
+export class DetailsComponent extends IntegrationComponentBase {
+ @property({ type: Object }) block: IBlock = {
+ integrationId: '',
+ acronym: '',
+ data: { details: {} as any, summary: [] }
+ };
+
+ @state() private _activeTab = '';
+ @state() private _expandedStates: Record = {};
+ @state() private _copiedStates: Record = {};
+
+ private _copyContentId = `copy-content-${Array.from(
+ crypto.getRandomValues(new Uint8Array(16)),
+ (b) => b.toString(16).padStart(2, '0')
+ ).join('')}`;
+
+ static styles = [
+ unsafeCSS(typographyCSS),
+ css`
+ :host {
+ display: block;
+ font-family: var(--pi-font-family-base, 'NotoSans', sans-serif);
+ font-size: var(--pi-size-font-base, 0.8125rem);
+ color: var(--pi-color-font-primary, #fafaff);
+ line-height: var(--pi-line-height-base, 1.4);
+ }
+
+ .copy-btn-container {
+ position: absolute;
+ right: 10px;
+ top: 7px;
+ z-index: 1;
+ }
+
+ .content-wrapper {
+ position: relative;
+ }
+
+ .tab-content {
+ display: flex;
+ flex-direction: column;
+ gap: var(--pi-size-spacing-xxs, 2px);
+ padding-top: var(--pi-size-spacing-xs, 4px);
+ }
+
+ .field-row {
+ display: flex;
+ align-items: baseline;
+ gap: var(--pi-size-spacing-xs, 4px);
+ flex-wrap: wrap;
+ }
+
+ .text-block {
+ margin-bottom: var(--pi-size-spacing-xs, 4px);
+ color: var(--pi-color-font-secondary, #cdced6);
+ }
+
+ .section-break {
+ border: none;
+ border-top: 1px solid var(--pi-color-border-container, #606470);
+ margin: var(--pi-size-spacing-sm, 8px) 0;
+ }
+
+ .expandable-title {
+ display: flex;
+ align-items: center;
+ gap: var(--pi-size-spacing-xs, 4px);
+ cursor: pointer;
+ background: none;
+ border: none;
+ padding: var(--pi-size-spacing-xxs, 2px) 0;
+ font-family: inherit;
+ font-size: inherit;
+ color: var(--pi-color-font-info, #33b2ff);
+ font-weight: var(--pi-font-weight-semibold, 600);
+ line-height: 1.2;
+ margin-bottom: var(--pi-size-spacing-xs, 4px);
+ }
+
+ .expandable-title:hover {
+ opacity: 0.8;
+ }
+
+ .expandable-title-text {
+ border-bottom: 1px solid var(--pi-color-font-info, #33b2ff);
+ }
+
+ .list-section {
+ margin-bottom: var(--pi-size-spacing-xs, 4px);
+ }
+
+ .list-items {
+ padding-left: var(--pi-size-spacing-sm, 8px);
+ display: flex;
+ flex-direction: column;
+ gap: var(--pi-size-spacing-xxs, 2px);
+ }
+
+ .list-item-fields {
+ padding-left: var(--pi-size-spacing-md, 12px);
+ display: flex;
+ flex-direction: column;
+ gap: var(--pi-size-spacing-xxs, 2px);
+ }
+
+ .copyable-field {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--pi-size-spacing-xs, 4px);
+ }
+
+ .copy-inline-btn {
+ cursor: pointer;
+ background: none;
+ border: none;
+ padding: 0;
+ display: inline-flex;
+ align-items: center;
+ color: var(--pi-color-font-secondary, #cdced6);
+ }
+
+ .copy-inline-btn:hover {
+ color: var(--pi-color-font-primary, #fafaff);
+ }
+
+ .copied-label {
+ font-size: var(--pi-size-font-xs, 0.75rem);
+ color: var(--pi-color-font-secondary, #cdced6);
+ }
+
+ .html-content {
+ padding-left: var(--pi-size-spacing-md, 12px);
+ margin-bottom: var(--pi-size-spacing-xs, 4px);
+ color: var(--pi-color-font-primary, #fafaff);
+ }
+
+ .link-list {
+ display: inline;
+ }
+
+ .kv-key {
+ color: var(--pi-color-font-secondary, #cdced6);
+ font-weight: var(--pi-font-weight-semibold, 600);
+ white-space: nowrap;
+ }
+
+ .link-separator {
+ color: var(--pi-color-font-secondary, #cdced6);
+ }
+
+ .indent-0 {
+ padding-left: 0;
+ }
+ .indent-1 {
+ padding-left: var(--pi-size-spacing-sm, 8px);
+ }
+ .indent-2 {
+ padding-left: var(--pi-size-spacing-lg, 16px);
+ }
+ .indent-3 {
+ padding-left: var(--pi-size-spacing-xl, 24px);
+ }
+ `
+ ];
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._initActiveTab();
+ }
+
+ updated(changedProperties: Map) {
+ super.updated(changedProperties);
+ if (changedProperties.has('block')) {
+ this._initActiveTab();
+ }
+ }
+
+ private _initActiveTab() {
+ const d = this.block.data?.details as Details | undefined;
+ if (!d?.tabKeys) return;
+
+ // Restore persisted tab from componentState, or pick first non-empty
+ const persisted = (this.block as any).componentState?.activeTab;
+ if (persisted && d.tabKeys.includes(persisted) && d[persisted]?.length) {
+ this._activeTab = persisted;
+ } else if (!this._activeTab || !d.tabKeys.includes(this._activeTab)) {
+ this._activeTab =
+ d.tabKeys.find((key) => d[key] && Array.isArray(d[key]) && d[key].length) ||
+ d.tabKeys[0] ||
+ '';
+ }
+ }
+
+ private _onTabChange(e: CustomEvent) {
+ const d = this.block.data?.details as Details;
+ if (!d?.tabKeys) return;
+ const tabIndex = e.detail?.tabIndex ?? 0;
+ const tabKey = d.tabKeys.filter((k) => d[k] && Array.isArray(d[k]) && d[k].length)[tabIndex];
+ if (tabKey) {
+ this._activeTab = tabKey;
+ // Persist active tab in componentState
+ if (this.block) {
+ (this.block as any).componentState = {
+ ...((this.block as any).componentState || {}),
+ activeTab: tabKey
+ };
+ }
+ }
+ }
+
+ private _toggleExpanded(key: string) {
+ this._expandedStates = {
+ ...this._expandedStates,
+ [key]: !this._expandedStates[key]
+ };
+ }
+
+ private _copyField(value: string, label: string, shouldCopyLabel: boolean, stateKey: string) {
+ const text = shouldCopyLabel ? `${label}: ${value}` : value;
+ navigator.clipboard.writeText(text);
+ this._copiedStates = { ...this._copiedStates, [stateKey]: true };
+ setTimeout(() => {
+ this._copiedStates = { ...this._copiedStates, [stateKey]: false };
+ }, 3000);
+ }
+
+ private _beforeCopy = async () => {
+ this.shadowRoot?.querySelectorAll('[data-pi-card]').forEach((card: any) => {
+ if (typeof card.expanded !== 'undefined') {
+ card.expanded = true;
+ }
+ });
+ await this.updateComplete;
+ };
+
+ private _afterCopy = async () => {
+ // No-op: cards remain expanded after copy
+ };
+
+ render() {
+ const d = this.block.data?.details as Details | undefined;
+ if (!d?.tabKeys?.length) return nothing;
+
+ const visibleTabs = d.tabKeys.filter((key) => d[key] && Array.isArray(d[key]) && d[key].length);
+
+ if (!visibleTabs.length) return nothing;
+
+ const activeIndex = Math.max(0, visibleTabs.indexOf(this._activeTab));
+
+ return html`
+
+
+
+ ${visibleTabs.length === 1
+ ? this._renderTabContent(d[visibleTabs[0]] as DisplayField[])
+ : html`
+
+ ${visibleTabs.map(
+ (tabKey, idx) => html`
+
+ ${humanizeTabKey(tabKey)}
+
+ `
+ )}
+ ${visibleTabs.map(
+ (tabKey, idx) => html`
+
+ ${this._renderTabContent(d[tabKey] as DisplayField[])}
+
+ `
+ )}
+
+ `}
+
+
+ `;
+ }
+
+ private _renderTabContent(fields: DisplayField[]) {
+ if (!fields?.length) return nothing;
+ return html`
+
+ ${fields.map((field, idx) => this._renderDisplayField(field, idx))}
+
+ `;
+ }
+
+ private _renderDisplayField(field: DisplayField, fieldIndex: number) {
+ if (field.isTitle) {
+ return this._renderTitle(field);
+ }
+ if (field.isTextBlock) {
+ return this._renderTextBlock(field);
+ }
+ if (field.isListOfLinks) {
+ return this._renderListOfLinks(field);
+ }
+ if (field.isHtml) {
+ return this._renderHtmlField(field, fieldIndex);
+ }
+ if (field.isList) {
+ return this._renderList(field, fieldIndex);
+ }
+ if (field.isNewSectionLineBreak) {
+ return html` `;
+ }
+ if (field.fieldIsCopyable) {
+ return this._renderCopyableField(field, fieldIndex, 0);
+ }
+ return this._renderKeyValue(field);
+ }
+
+ private _renderTitle(field: DisplayField) {
+ const indentClass = `indent-${field.indent || 0}`;
+ const labelText = field.capitalize
+ ? capitalizeStr(field.label || field.value || '')
+ : field.label || field.value || '';
+
+ if (field.displayLink && (field.value || field.label)) {
+ if (field.showLabelAndValue) {
+ return html`
+
+
+
+ `;
+ }
+ return html`
+
+
+
+ `;
+ }
+
+ if (field.showLabelAndValue) {
+ return html`${field.label}: ${field.value} `;
+ }
+
+ return html`${labelText} `;
+ }
+
+ private _renderTextBlock(field: DisplayField) {
+ const indentClass = `indent-${field.indent || 0}`;
+ const text = field.capitalize ? capitalizeStr(field.value) : field.value;
+ return html`${text}
`;
+ }
+
+ private _renderListOfLinks(field: DisplayField) {
+ const indentClass = `indent-${field.indent || 0}`;
+ const links = field.value as Array<{ url: string; id: string; capitalize?: boolean }>;
+ return html`
+
+
${field.label}:
+
+ ${links.map(
+ // prettier-ignore
+ (link, i) => html` ${i < links.length - 1
+ ? html`, `
+ : nothing}`
+ )}
+
+
+ `;
+ }
+
+ private _renderHtmlField(field: DisplayField, fieldIndex: number) {
+ const stateKey = `${fieldIndex}-0-${field.label}`;
+ const isExpanded = !!this._expandedStates[stateKey];
+ return html`
+
+
this._toggleExpanded(stateKey)}
+ aria-expanded=${isExpanded}
+ >
+ ${field.label}
+
+
+ ${isExpanded ? html`
${unsafeHTML(field.value)}
` : nothing}
+
+ `;
+ }
+
+ private _renderList(field: DisplayField, fieldIndex: number) {
+ const items = field.value as DisplayField[][];
+ if (!items?.length) return nothing;
+
+ return html`
+
+
${field.label}
+
+ ${items.map((itemFields, itemIdx) =>
+ field.collapsibleListItems
+ ? this._renderCollapsibleListItem(field, fieldIndex, itemFields, itemIdx)
+ : this._renderFlatListItem(itemFields, fieldIndex, itemIdx)
+ )}
+
+
+ `;
+ }
+
+ private _renderCollapsibleListItem(
+ parentField: DisplayField,
+ fieldIndex: number,
+ itemFields: DisplayField[],
+ itemIdx: number
+ ) {
+ const stateKey = `${fieldIndex}-${itemIdx}-${parentField.label}`;
+ const isExpanded = !!this._expandedStates[stateKey];
+ const headerValue = itemFields[0]?.value ?? '';
+
+ return html`
+
+
this._toggleExpanded(stateKey)}
+ aria-expanded=${isExpanded}
+ >
+ ${headerValue}
+
+
+ ${isExpanded
+ ? html`
+
+ ${itemFields
+ .slice(1)
+ .map((itemField, subIdx) =>
+ this._renderListItemField(itemField, fieldIndex, subIdx + 1)
+ )}
+
+ `
+ : nothing}
+
+ `;
+ }
+
+ private _renderFlatListItem(itemFields: DisplayField[], fieldIndex: number, _itemIdx: number) {
+ return html`
+
+ ${itemFields.map((itemField, subIdx) =>
+ this._renderListItemField(itemField, fieldIndex, subIdx)
+ )}
+
+ `;
+ }
+
+ private _renderListItemField(field: DisplayField, fieldIndex: number, subIndex: number) {
+ const value = field.isDate ? formatDate(field.value) : field.value;
+ const copyStateKey = `${fieldIndex}-${field.label}-${subIndex}`;
+
+ if (field.fieldIsCopyable) {
+ return html`
+
+
+
+ this._copyField(
+ String(field.value),
+ field.label || '',
+ !!field.shouldCopyFieldLabel,
+ copyStateKey
+ )}
+ >
+
+
+ ${this._copiedStates[copyStateKey]
+ ? html`
Copied `
+ : nothing}
+
+ `;
+ }
+
+ return html` `;
+ }
+
+ private _renderCopyableField(field: DisplayField, fieldIndex: number, subIndex: number) {
+ const indentClass = `indent-${field.indent || 0}`;
+ const value = field.isDate
+ ? formatDate(field.value)
+ : field.capitalize
+ ? capitalizeStr(field.value)
+ : field.value;
+ const copyStateKey = `${fieldIndex}-${field.label}-${subIndex}`;
+
+ return html`
+
+
+
+ this._copyField(
+ String(field.value),
+ field.label || '',
+ !!field.shouldCopyFieldLabel,
+ copyStateKey
+ )}
+ >
+
+
+ ${this._copiedStates[copyStateKey]
+ ? html`
Copied `
+ : nothing}
+
+ `;
+ }
+
+ private _renderKeyValue(field: DisplayField) {
+ const indentClass = `indent-${field.indent || 0}`;
+
+ if (field.isDate) {
+ return html`
+
+ `;
+ }
+
+ if (field.displayLink) {
+ const displayText = field.capitalize ? capitalizeStr(field.value) : field.value;
+ return html`
+
+ `;
+ }
+
+ const value = field.capitalize ? capitalizeStr(field.value) : field.value;
+ return html`
+
+ `;
+ }
+}