diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml
index eae056eca..1a2e219bb 100644
--- a/.github/workflows/package.yml
+++ b/.github/workflows/package.yml
@@ -40,7 +40,7 @@ jobs:
- name: Checkout source
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Download package
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: testrun_package
- name: Install dependencies
@@ -74,7 +74,7 @@ jobs:
- name: Checkout source
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Download package
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: testrun_package
- name: Install dependencies
@@ -108,7 +108,7 @@ jobs:
- name: Checkout source
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Download package
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: testrun_package
- name: Install dependencies
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index 9ba417f9f..4e78f18b5 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -69,10 +69,6 @@ jobs:
- name: Install Testrun
shell: bash {0}
run: cmd/install -l
- - name: Build Testrun
- shell: bash {0}
- run: cmd/build
- timeout-minutes: 10
- name: Run tests for conn module
shell: bash {0}
run: bash testing/unit/run_test_module.sh conn captures ethtool output
diff --git a/docs/dev/mockoon.json b/docs/dev/mockoon.json
index a73eb5beb..394800402 100644
--- a/docs/dev/mockoon.json
+++ b/docs/dev/mockoon.json
@@ -605,7 +605,7 @@
"responses": [
{
"uuid": "9536ff4c-f97f-4880-b9fc-f477686ad6b8",
- "body": "[\n {\n \"mac_addr\": \"00:1e:42:35:73:c6\",\n \"device\": {\n \"mac_addr\": \"00:1e:42:35:73:c4\",\n \"manufacturer\": \"Teltonika\",\n \"model\": \"TRB140\",\n \"firmware\": \"1.2.3\",\n \"test_modules\": {\n \"connection\": {\n \"enabled\": false\n },\n \"ntp\": {\n \"enabled\": true\n },\n \"dns\": {\n \"enabled\": true\n },\n \"services\": {\n \"enabled\": true\n },\n \"tls\": {\n \"enabled\": true\n },\n \"protocol\": {\n \"enabled\": true\n }\n }\n },\n \"status\": \"Non-Compliant\",\n \"started\": \"2024-05-03 12:09:59\",\n \"finished\": \"2024-05-03 12:15:51\",\n \"tests\": {\n \"total\": 20,\n \"results\": [\n {\n \"name\": \"protocol.valid_bacnet\",\n \"description\": \"BACnet discovery could not resolve any devices\",\n \"expected_behavior\": \"BACnet traffic can be seen on the network and packets are valid and not malformed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Skipped\"\n },\n {\n \"name\": \"protocol.bacnet.version\",\n \"description\": \"No BACnet devices discovered.\",\n \"expected_behavior\": \"The BACnet client implements an up to date version of BACnet\",\n \"required_result\": \"Recommended\",\n \"result\": \"Skipped\"\n },\n {\n \"name\": \"protocol.valid_modbus\",\n \"description\": \"Failed to establish Modbus connection to device\",\n \"expected_behavior\": \"Any Modbus functionality works as expected and valid Modbus traffic can be observed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_support\",\n \"description\": \"Device sent NTPv3 packets. NTPv3 is not allowed.\",\n \"expected_behavior\": \"The device sends an NTPv4 request to the configured NTP server.\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_dhcp\",\n \"description\": \"Device sent NTP request to non-DHCP provided server\",\n \"expected_behavior\": \"Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)\",\n \"required_result\": \"Roadmap\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"security.services.ftp\",\n \"description\": \"No FTP server found\",\n \"expected_behavior\": \"There is no FTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.ssh.version\",\n \"description\": \"SSH server found running protocol 2.0\",\n \"expected_behavior\": \"SSH server is not running or server is SSHv2\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.telnet\",\n \"description\": \"No telnet server found\",\n \"expected_behavior\": \"There is no Telnet service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.smtp\",\n \"description\": \"No SMTP server found\",\n \"expected_behavior\": \"There is no SMTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.http\",\n \"description\": \"Found HTTP server running on port 80/tcp\",\n \"expected_behavior\": \"Device is unreachable on port 80 (or any other port) and only responds to HTTPS requests on port 443 (or any other port if HTTP is used at all)\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"security.services.pop\",\n \"description\": \"No POP server found\",\n \"expected_behavior\": \"There is no POP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.imap\",\n \"description\": \"No IMAP server found\",\n \"expected_behavior\": \"There is no IMAP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.snmpv3\",\n \"description\": \"No SNMP server found\",\n \"expected_behavior\": \"Device is unreachable on port 161 (or any other port) and device is unreachable on port 162 (or any other port) unless SNMP is essential in which case it is SNMPv3 is used.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.vnc\",\n \"description\": \"No VNC server found\",\n \"expected_behavior\": \"Device cannot be accessed / connected to via VNC on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.tftp\",\n \"description\": \"No TFTP server found\",\n \"expected_behavior\": \"There is no TFTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_server\",\n \"description\": \"No NTP server found\",\n \"expected_behavior\": \"The device does not respond to NTP requests when it's IP is set as the NTP server on another device\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"dns.network.hostname_resolution\",\n \"description\": \"DNS traffic detected from device\",\n \"expected_behavior\": \"The device sends DNS requests.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"dns.network.from_dhcp\",\n \"description\": \"DNS traffic detected only to DHCP provided server\",\n \"expected_behavior\": \"The device sends DNS requests to the DNS server provided by the DHCP server\",\n \"required_result\": \"Roadmap\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.tls.v1_2_server\",\n \"description\": \"TLS 1.2 not validated: Certificate has expired\\nEC key length passed: 256 >= 224\\nDevice certificate has not been signed\\nTLS 1.3 not validated: Certificate has expired\\nEC key length passed: 256 >= 224\\nDevice certificate has not been signed\",\n \"expected_behavior\": \"TLS 1.2 certificate is issued to the web browser client when accessed\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"security.tls.v1_2_client\",\n \"description\": \"No outbound connections were found.\",\n \"expected_behavior\": \"The packet indicates a TLS connection with at least TLS 1.2 and support for ECDH and ECDSA ciphers\",\n \"required_result\": \"Required\",\n \"result\": \"Skipped\"\n }\n ]\n },\n \"report\": \"http://localhost:8000/report/123 123/2024-05-03T12:09:59\"\n }\n]",
+ "body": "[\n {\n \"mac_addr\": \"00:1e:42:35:73:c6\",\n \"device\": {\n \"mac_addr\": \"00:1e:42:35:73:c4\",\n \"manufacturer\": \"Teltonika\",\n \"model\": \"TRB140\",\n \"firmware\": \"1.2.3\",\n \"test_modules\": {\n \"connection\": {\n \"enabled\": false\n },\n \"ntp\": {\n \"enabled\": true\n },\n \"dns\": {\n \"enabled\": true\n },\n \"services\": {\n \"enabled\": true\n },\n \"tls\": {\n \"enabled\": true\n },\n \"protocol\": {\n \"enabled\": true\n }\n }\n },\n \"status\": \"Non-Compliant\",\n \"started\": \"2024-05-03 12:09:59\",\n \"finished\": \"2024-05-03 12:15:51\",\n \"tests\": {\n \"total\": 20,\n \"results\": [\n {\n \"name\": \"protocol.valid_bacnet\",\n \"description\": \"BACnet discovery could not resolve any devices\",\n \"expected_behavior\": \"BACnet traffic can be seen on the network and packets are valid and not malformed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Skipped\"\n },\n {\n \"name\": \"protocol.bacnet.version\",\n \"description\": \"No BACnet devices discovered.\",\n \"expected_behavior\": \"The BACnet client implements an up to date version of BACnet\",\n \"required_result\": \"Recommended\",\n \"result\": \"Skipped\"\n },\n {\n \"name\": \"protocol.valid_modbus\",\n \"description\": \"Failed to establish Modbus connection to device\",\n \"expected_behavior\": \"Any Modbus functionality works as expected and valid Modbus traffic can be observed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_support\",\n \"description\": \"Device sent NTPv3 packets. NTPv3 is not allowed.\",\n \"expected_behavior\": \"The device sends an NTPv4 request to the configured NTP server.\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_dhcp\",\n \"description\": \"Device sent NTP request to non-DHCP provided server\",\n \"expected_behavior\": \"Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)\",\n \"required_result\": \"Roadmap\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"security.services.ftp\",\n \"description\": \"No FTP server found\",\n \"expected_behavior\": \"There is no FTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.ssh.version\",\n \"description\": \"SSH server found running protocol 2.0\",\n \"expected_behavior\": \"SSH server is not running or server is SSHv2\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.telnet\",\n \"description\": \"No telnet server found\",\n \"expected_behavior\": \"There is no Telnet service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.smtp\",\n \"description\": \"No SMTP server found\",\n \"expected_behavior\": \"There is no SMTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.http\",\n \"description\": \"Found HTTP server running on port 80/tcp\",\n \"expected_behavior\": \"Device is unreachable on port 80 (or any other port) and only responds to HTTPS requests on port 443 (or any other port if HTTP is used at all)\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"security.services.pop\",\n \"description\": \"No POP server found\",\n \"expected_behavior\": \"There is no POP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.imap\",\n \"description\": \"No IMAP server found\",\n \"expected_behavior\": \"There is no IMAP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.snmpv3\",\n \"description\": \"No SNMP server found\",\n \"expected_behavior\": \"Device is unreachable on port 161 (or any other port) and device is unreachable on port 162 (or any other port) unless SNMP is essential in which case it is SNMPv3 is used.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.vnc\",\n \"description\": \"No VNC server found\",\n \"expected_behavior\": \"Device cannot be accessed / connected to via VNC on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.tftp\",\n \"description\": \"No TFTP server found\",\n \"expected_behavior\": \"There is no TFTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_server\",\n \"description\": \"No NTP server found\",\n \"expected_behavior\": \"The device does not respond to NTP requests when it's IP is set as the NTP server on another device\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"dns.network.hostname_resolution\",\n \"description\": \"DNS traffic detected from device\",\n \"expected_behavior\": \"The device sends DNS requests.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"dns.network.from_dhcp\",\n \"description\": \"DNS traffic detected only to DHCP provided server\",\n \"expected_behavior\": \"The device sends DNS requests to the DNS server provided by the DHCP server\",\n \"required_result\": \"Roadmap\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.tls.v1_2_server\",\n \"description\": \"TLS 1.2 not validated: Certificate has expired\\nEC key length passed: 256 >= 224\\nDevice certificate has not been signed\\nTLS 1.3 not validated: Certificate has expired\\nEC key length passed: 256 >= 224\\nDevice certificate has not been signed\",\n \"expected_behavior\": \"TLS 1.2 certificate is issued to the web browser client when accessed\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\"\n },\n {\n \"name\": \"security.tls.v1_2_client\",\n \"description\": \"No outbound TLS connections were found.\",\n \"expected_behavior\": \"The packet indicates a TLS connection with at least TLS 1.2 and support for ECDH and ECDSA ciphers\",\n \"required_result\": \"Required\",\n \"result\": \"Skipped\"\n }\n ]\n },\n \"report\": \"http://localhost:8000/report/123 123/2024-05-03T12:09:59\"\n }\n]",
"latency": 0,
"statusCode": 200,
"label": "",
@@ -1602,6 +1602,111 @@
}
],
"responseMode": null
+ },
+ {
+ "uuid": "af7fdcb0-721d-4198-a8ef-c6d8c4eba8c8",
+ "type": "http",
+ "documentation": "Get a Testrun PDF profile",
+ "method": "post",
+ "endpoint": "report/{profile_name}",
+ "responses": [
+ {
+ "uuid": "9a759f46-4bc4-433a-be86-e456f069c217",
+ "body": "",
+ "latency": 0,
+ "statusCode": 200,
+ "label": "Profile found - no device selected",
+ "headers": [],
+ "bodyType": "FILE",
+ "filePath": "",
+ "databucketID": "",
+ "sendFileAsBody": false,
+ "rules": [],
+ "rulesOperator": "OR",
+ "disableTemplating": false,
+ "fallbackTo404": false,
+ "default": true,
+ "crudKey": "id",
+ "callbacks": []
+ },
+ {
+ "uuid": "c9a09ae7-3158-4956-93ac-4c8a90dfced8",
+ "body": "",
+ "latency": 0,
+ "statusCode": 200,
+ "label": "Profile found - device selected ",
+ "headers": [],
+ "bodyType": "FILE",
+ "filePath": "",
+ "databucketID": "",
+ "sendFileAsBody": false,
+ "rules": [],
+ "rulesOperator": "OR",
+ "disableTemplating": false,
+ "fallbackTo404": false,
+ "default": false,
+ "crudKey": "id",
+ "callbacks": []
+ },
+ {
+ "uuid": "5f98471e-15b6-47a4-a68d-e98c3a538b40",
+ "body": "{\n \"error\": \"Profile could not be found\"\n}",
+ "latency": 0,
+ "statusCode": 404,
+ "label": "Profile not found",
+ "headers": [],
+ "bodyType": "INLINE",
+ "filePath": "",
+ "databucketID": "",
+ "sendFileAsBody": false,
+ "rules": [],
+ "rulesOperator": "OR",
+ "disableTemplating": false,
+ "fallbackTo404": false,
+ "default": false,
+ "crudKey": "id",
+ "callbacks": []
+ },
+ {
+ "uuid": "767d9e78-386e-4bf7-bec8-71a005efdce9",
+ "body": "{\n \"error\": \"A device with that mac address could not be found\"\n}",
+ "latency": 0,
+ "statusCode": 404,
+ "label": "Device not found",
+ "headers": [],
+ "bodyType": "INLINE",
+ "filePath": "",
+ "databucketID": "",
+ "sendFileAsBody": false,
+ "rules": [],
+ "rulesOperator": "OR",
+ "disableTemplating": false,
+ "fallbackTo404": false,
+ "default": false,
+ "crudKey": "id",
+ "callbacks": []
+ },
+ {
+ "uuid": "5d76bea0-39c1-45f2-80f1-de6f770cb999",
+ "body": "{\n \"error\": \"Error retrieving the profile PDF\"\n}",
+ "latency": 0,
+ "statusCode": 500,
+ "label": "Error occured",
+ "headers": [],
+ "bodyType": "INLINE",
+ "filePath": "",
+ "databucketID": "",
+ "sendFileAsBody": false,
+ "rules": [],
+ "rulesOperator": "OR",
+ "disableTemplating": false,
+ "fallbackTo404": false,
+ "default": false,
+ "crudKey": "id",
+ "callbacks": []
+ }
+ ],
+ "responseMode": null
}
],
"rootChildren": [
@@ -1700,6 +1805,10 @@
{
"type": "route",
"uuid": "26f0f76f-e787-4ebe-a3f8-ea3a6004bc15"
+ },
+ {
+ "type": "route",
+ "uuid": "af7fdcb0-721d-4198-a8ef-c6d8c4eba8c8"
}
],
"proxyMode": false,
diff --git a/docs/dev/postman.json b/docs/dev/postman.json
index 642090dd4..1e8a9cafb 100644
--- a/docs/dev/postman.json
+++ b/docs/dev/postman.json
@@ -1068,7 +1068,7 @@
}
],
"cookie": [],
- "body": "[\n {\n \"testrun\": {\n \"version\": \"2.0\"\n },\n \"mac_addr\": \"00:1e:42:28:9e:4a\",\n \"device\": {\n \"mac_addr\": \"00:1e:42:28:9e:4a\",\n \"manufacturer\": \"Teltonika\",\n \"model\": \"TRB140\",\n \"firmware\": \"test\",\n \"test_modules\": {\n \"protocol\": {\n \"enabled\": true\n },\n \"services\": {\n \"enabled\": true\n },\n \"ntp\": {\n \"enabled\": true\n },\n \"tls\": {\n \"enabled\": true\n },\n \"connection\": {\n \"enabled\": true\n },\n \"dns\": {\n \"enabled\": true\n }\n }\n },\n \"status\": \"Non-Compliant\",\n \"started\": \"2000-01-01 00:00:00\",\n \"finished\": \"2000-01-01 00:30:00\",\n \"tests\": {\n \"total\": 40,\n \"results\": [\n {\n \"name\": \"protocol.valid_bacnet\",\n \"description\": \"BACnet device could not be discovered\",\n \"expected_behavior\": \"BACnet traffic can be seen on the network and packets are valid and not malformed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"protocol.bacnet.version\",\n \"description\": \"Device did not respond to BACnet discovery\",\n \"expected_behavior\": \"The BACnet client implements an up to date version of BACnet\",\n \"required_result\": \"Recommended\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"protocol.valid_modbus\",\n \"description\": \"Device did not respond to Modbus connection\",\n \"expected_behavior\": \"Any Modbus functionality works as expected and valid Modbus traffic can be observed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"security.services.ftp\",\n \"description\": \"No FTP server found\",\n \"expected_behavior\": \"There is no FTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.ssh.version\",\n \"description\": \"SSH server found running protocol 2.0\",\n \"expected_behavior\": \"SSH server is not running or server is SSHv2\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.telnet\",\n \"description\": \"No telnet server found\",\n \"expected_behavior\": \"There is no Telnet service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.smtp\",\n \"description\": \"No SMTP server found\",\n \"expected_behavior\": \"There is no SMTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.http\",\n \"description\": \"Found HTTP server running on port 80/tcp\",\n \"expected_behavior\": \"Device is unreachable on port 80 (or any other port) and only responds to HTTPS requests on port 443 (or any other port if HTTP is used at all)\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Disable all unsecure HTTP servers\",\n \"Setup TLS on the web server\"\n ]\n },\n {\n \"name\": \"security.services.pop\",\n \"description\": \"No POP server found\",\n \"expected_behavior\": \"There is no POP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.imap\",\n \"description\": \"No IMAP server found\",\n \"expected_behavior\": \"There is no IMAP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.snmpv3\",\n \"description\": \"No SNMP server found\",\n \"expected_behavior\": \"Device is unreachable on port 161 (or any other port) and device is unreachable on port 162 (or any other port) unless SNMP is essential in which case it is SNMPv3 is used.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.vnc\",\n \"description\": \"No VNC server found\",\n \"expected_behavior\": \"Device cannot be accessed / connected to via VNC on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.tftp\",\n \"description\": \"No TFTP server found\",\n \"expected_behavior\": \"There is no TFTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_server\",\n \"description\": \"No NTP server found\",\n \"expected_behavior\": \"The device does not respond to NTP requests when it's IP is set as the NTP server on another device\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.port_link\",\n \"description\": \"No port errors detected\",\n \"expected_behavior\": \"When the etherent cable is connected to the port, the device triggers the port to its enabled \\\"Link UP\\\" (LEDs illuminate on device and switch ports if present) state, and the switch shows no errors with the LEDs and when interrogated with a \\\"show interface\\\" command on most network switches.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.port_speed\",\n \"description\": \"Succesfully auto-negotiated speeds above 10 Mbps\",\n \"expected_behavior\": \"When the ethernet cable is connected to the port, the device autonegotiates a speed that can be checked with the \\\"show interface\\\" command on most network switches. The output of this command must also show that the \\\"configured speed\\\" is set to \\\"auto\\\".\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.port_duplex\",\n \"description\": \"Succesfully auto-negotiated full duplex\",\n \"expected_behavior\": \"When the ethernet cable is connected to the port, the device autonegotiates a full-duplex connection.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.switch.arp_inspection\",\n \"description\": \"Device uses ARP\",\n \"expected_behavior\": \"Device continues to operate correctly when ARP inspection is enabled on the switch. No functionality is lost with ARP inspection enabled.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.switch.dhcp_snooping\",\n \"description\": \"Device does not act as a DHCP server\",\n \"expected_behavior\": \"Device continues to operate correctly when DHCP snooping is enabled on the switch.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.dhcp_address\",\n \"description\": \"Device responded to leased ip address\",\n \"expected_behavior\": \"The device is not setup with a static IP address. The device accepts an IP address from a DHCP server (RFC 2131) and responds succesfully to an ICMP echo (ping) request.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.mac_address\",\n \"description\": \"MAC address found: 00:1e:42:28:9e:4a\",\n \"expected_behavior\": \"N/A\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.mac_oui\",\n \"description\": \"OUI Manufacturer found: Teltonika\",\n \"expected_behavior\": \"The MAC address prefix is registered in the IEEE Organizationally Unique Identifier database.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.private_address\",\n \"description\": \"All subnets are supported\",\n \"expected_behavior\": \"The device under test accepts IP addresses within all ranges specified in RFC 1918 and communicates using these addresses. The Internet Assigned Numbers Authority (IANA) has reserved the following three blocks of the IP address space for private internets. 10.0.0.0 - 10.255.255.255.255 (10/8 prefix). 172.16.0.0 - 172.31.255.255 (172.16/12 prefix). 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.shared_address\",\n \"description\": \"All subnets are supported\",\n \"expected_behavior\": \"The device under test accepts IP addresses within the ranges specified in RFC 6598 and communicates using these addresses\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.dhcp_disconnect\",\n \"description\": \"An error occured whilst running this test\",\n \"expected_behavior\": \"A client SHOULD use DHCP to reacquire or verify its IP address and network parameters whenever the local network parameters may have changed; e.g., at system boot time or after a disconnection from the local network, as the local network configuration may change without the client's or user's knowledge. If a client has knowledge ofa previous network address and is unable to contact a local DHCP server, the client may continue to use the previous network addres until the lease for that address expires. If the lease expires before the client can contact a DHCP server, the client must immediately discontinue use of the previous network address and may inform local users of the problem.\",\n \"required_result\": \"Required\",\n \"result\": \"Error\"\n },\n {\n \"name\": \"connection.single_ip\",\n \"description\": \"Device is using multiple IP addresses\",\n \"expected_behavior\": \"The device under test does not behave as a network switch and only requets one IP address. This test is to avoid that devices implement network switches that allow connecting strings of daisy chained devices to one single network port, as this would not make 802.1x port based authentication possible.\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Ensure that all ports on the device are isolated\",\n \"Ensure only one DHCP client is running\"\n ]\n },\n {\n \"name\": \"connection.target_ping\",\n \"description\": \"Device responds to ping\",\n \"expected_behavior\": \"The device under test responds to an ICMP echo (ping) request.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.ipaddr.ip_change\",\n \"description\": \"Device has accepted an IP address change\",\n \"expected_behavior\": \"If the lease expires before the client receiveds a DHCPACK, the client moves to INIT state, MUST immediately stop any other network processing and requires network initialization parameters as if the client were uninitialized. If the client then receives a DHCPACK allocating the client its previous network addres, the client SHOULD continue network processing. If the client is given a new network address, it MUST NOT continue using the previous network address and SHOULD notify the local users of the problem.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.ipaddr.dhcp_failover\",\n \"description\": \"Secondary DHCP server lease confirmed active in device\",\n \"expected_behavior\": \"\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.ipv6_slaac\",\n \"description\": \"Device does not support IPv6 SLAAC\",\n \"expected_behavior\": \"The device under test complies with RFC4862 and forms a valid IPv6 SLAAC address\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Install a network manager that supports IPv6\",\n \"Disable DHCPv6\"\n ]\n },\n {\n \"name\": \"connection.ipv6_ping\",\n \"description\": \"No IPv6 SLAAC address found. Cannot ping\",\n \"expected_behavior\": \"The device responds to the ping as per RFC4443\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Enable ping response to IPv6 ICMP requests in network manager settings\",\n \"Create a firewall exception to allow ICMPv6 via LAN\"\n ]\n },\n {\n \"name\": \"security.tls.v1_2_server\",\n \"description\": \"TLS 1.2 certificate is invalid\",\n \"expected_behavior\": \"TLS 1.2 certificate is issued to the web browser client when accessed\",\n \"required_result\": \"Required if Applicable\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Enable TLS 1.2 support in the web server configuration\",\n \"Disable TLS 1.0 and 1.1\",\n \"Sign the certificate used by the web server\"\n ]\n },\n {\n \"name\": \"security.tls.v1_2_client\",\n \"description\": \"No outbound connections were found\",\n \"expected_behavior\": \"The packet indicates a TLS connection with at least TLS 1.2 and support for ECDH and ECDSA ciphers\",\n \"required_result\": \"Required if Applicable\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"security.tls.v1_3_server\",\n \"description\": \"TLS 1.3 certificate is invalid\",\n \"expected_behavior\": \"TLS 1.3 certificate is issued to the web browser client when accessed\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n },\n {\n \"name\": \"security.tls.v1_3_client\",\n \"description\": \"No outbound connections were found\",\n \"expected_behavior\": \"The packet indicates a TLS connection with at least TLS 1.3\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n },\n {\n \"name\": \"ntp.network.ntp_support\",\n \"description\": \"Device has not sent any NTP requests\",\n \"expected_behavior\": \"The device sends an NTPv4 request to the configured NTP server.\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Set the NTP version to v4 in the NTP client\",\n \"Install an NTP client that supports NTPv4\"\n ]\n },\n {\n \"name\": \"ntp.network.ntp_dhcp\",\n \"description\": \"Device has not sent any NTP requests\",\n \"expected_behavior\": \"Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)\",\n \"required_result\": \"Roadmap\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"dns.network.hostname_resolution\",\n \"description\": \"DNS traffic detected from device\",\n \"expected_behavior\": \"The device sends DNS requests.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"dns.network.from_dhcp\",\n \"description\": \"DNS traffic detected only to DHCP provided server\",\n \"expected_behavior\": \"The device sends DNS requests to the DNS server provided by the DHCP server\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n },\n {\n \"name\": \"dns.mdns\",\n \"description\": \"No MDNS traffic detected from the device\",\n \"expected_behavior\": \"Device may send MDNS requests\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n }\n ]\n },\n \"report\": \"http://localhost:8000/report/Teltonika TRB140/2024-09-10T13:19:24\"\n }\n]"
+ "body": "[\n {\n \"testrun\": {\n \"version\": \"2.0\"\n },\n \"mac_addr\": \"00:1e:42:28:9e:4a\",\n \"device\": {\n \"mac_addr\": \"00:1e:42:28:9e:4a\",\n \"manufacturer\": \"Teltonika\",\n \"model\": \"TRB140\",\n \"firmware\": \"test\",\n \"test_modules\": {\n \"protocol\": {\n \"enabled\": true\n },\n \"services\": {\n \"enabled\": true\n },\n \"ntp\": {\n \"enabled\": true\n },\n \"tls\": {\n \"enabled\": true\n },\n \"connection\": {\n \"enabled\": true\n },\n \"dns\": {\n \"enabled\": true\n }\n }\n },\n \"status\": \"Non-Compliant\",\n \"started\": \"2000-01-01 00:00:00\",\n \"finished\": \"2000-01-01 00:30:00\",\n \"tests\": {\n \"total\": 40,\n \"results\": [\n {\n \"name\": \"protocol.valid_bacnet\",\n \"description\": \"BACnet device could not be discovered\",\n \"expected_behavior\": \"BACnet traffic can be seen on the network and packets are valid and not malformed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"protocol.bacnet.version\",\n \"description\": \"Device did not respond to BACnet discovery\",\n \"expected_behavior\": \"The BACnet client implements an up to date version of BACnet\",\n \"required_result\": \"Recommended\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"protocol.valid_modbus\",\n \"description\": \"Device did not respond to Modbus connection\",\n \"expected_behavior\": \"Any Modbus functionality works as expected and valid Modbus traffic can be observed\",\n \"required_result\": \"Recommended\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"security.services.ftp\",\n \"description\": \"No FTP server found\",\n \"expected_behavior\": \"There is no FTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.ssh.version\",\n \"description\": \"SSH server found running protocol 2.0\",\n \"expected_behavior\": \"SSH server is not running or server is SSHv2\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.telnet\",\n \"description\": \"No telnet server found\",\n \"expected_behavior\": \"There is no Telnet service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.smtp\",\n \"description\": \"No SMTP server found\",\n \"expected_behavior\": \"There is no SMTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.http\",\n \"description\": \"Found HTTP server running on port 80/tcp\",\n \"expected_behavior\": \"Device is unreachable on port 80 (or any other port) and only responds to HTTPS requests on port 443 (or any other port if HTTP is used at all)\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Disable all unsecure HTTP servers\",\n \"Setup TLS on the web server\"\n ]\n },\n {\n \"name\": \"security.services.pop\",\n \"description\": \"No POP server found\",\n \"expected_behavior\": \"There is no POP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.imap\",\n \"description\": \"No IMAP server found\",\n \"expected_behavior\": \"There is no IMAP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.snmpv3\",\n \"description\": \"No SNMP server found\",\n \"expected_behavior\": \"Device is unreachable on port 161 (or any other port) and device is unreachable on port 162 (or any other port) unless SNMP is essential in which case it is SNMPv3 is used.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.vnc\",\n \"description\": \"No VNC server found\",\n \"expected_behavior\": \"Device cannot be accessed / connected to via VNC on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"security.services.tftp\",\n \"description\": \"No TFTP server found\",\n \"expected_behavior\": \"There is no TFTP service running on any port\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"ntp.network.ntp_server\",\n \"description\": \"No NTP server found\",\n \"expected_behavior\": \"The device does not respond to NTP requests when it's IP is set as the NTP server on another device\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.port_link\",\n \"description\": \"No port errors detected\",\n \"expected_behavior\": \"When the etherent cable is connected to the port, the device triggers the port to its enabled \\\"Link UP\\\" (LEDs illuminate on device and switch ports if present) state, and the switch shows no errors with the LEDs and when interrogated with a \\\"show interface\\\" command on most network switches.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.port_speed\",\n \"description\": \"Succesfully auto-negotiated speeds above 10 Mbps\",\n \"expected_behavior\": \"When the ethernet cable is connected to the port, the device autonegotiates a speed that can be checked with the \\\"show interface\\\" command on most network switches. The output of this command must also show that the \\\"configured speed\\\" is set to \\\"auto\\\".\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.port_duplex\",\n \"description\": \"Succesfully auto-negotiated full duplex\",\n \"expected_behavior\": \"When the ethernet cable is connected to the port, the device autonegotiates a full-duplex connection.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.switch.arp_inspection\",\n \"description\": \"Device uses ARP\",\n \"expected_behavior\": \"Device continues to operate correctly when ARP inspection is enabled on the switch. No functionality is lost with ARP inspection enabled.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.switch.dhcp_snooping\",\n \"description\": \"Device does not act as a DHCP server\",\n \"expected_behavior\": \"Device continues to operate correctly when DHCP snooping is enabled on the switch.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.dhcp_address\",\n \"description\": \"Device responded to leased ip address\",\n \"expected_behavior\": \"The device is not setup with a static IP address. The device accepts an IP address from a DHCP server (RFC 2131) and responds succesfully to an ICMP echo (ping) request.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.mac_address\",\n \"description\": \"MAC address found: 00:1e:42:28:9e:4a\",\n \"expected_behavior\": \"N/A\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.mac_oui\",\n \"description\": \"OUI Manufacturer found: Teltonika\",\n \"expected_behavior\": \"The MAC address prefix is registered in the IEEE Organizationally Unique Identifier database.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.private_address\",\n \"description\": \"All subnets are supported\",\n \"expected_behavior\": \"The device under test accepts IP addresses within all ranges specified in RFC 1918 and communicates using these addresses. The Internet Assigned Numbers Authority (IANA) has reserved the following three blocks of the IP address space for private internets. 10.0.0.0 - 10.255.255.255.255 (10/8 prefix). 172.16.0.0 - 172.31.255.255 (172.16/12 prefix). 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.shared_address\",\n \"description\": \"All subnets are supported\",\n \"expected_behavior\": \"The device under test accepts IP addresses within the ranges specified in RFC 6598 and communicates using these addresses\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.dhcp_disconnect\",\n \"description\": \"An error occured whilst running this test\",\n \"expected_behavior\": \"A client SHOULD use DHCP to reacquire or verify its IP address and network parameters whenever the local network parameters may have changed; e.g., at system boot time or after a disconnection from the local network, as the local network configuration may change without the client's or user's knowledge. If a client has knowledge ofa previous network address and is unable to contact a local DHCP server, the client may continue to use the previous network addres until the lease for that address expires. If the lease expires before the client can contact a DHCP server, the client must immediately discontinue use of the previous network address and may inform local users of the problem.\",\n \"required_result\": \"Required\",\n \"result\": \"Error\"\n },\n {\n \"name\": \"connection.single_ip\",\n \"description\": \"Device is using multiple IP addresses\",\n \"expected_behavior\": \"The device under test does not behave as a network switch and only requets one IP address. This test is to avoid that devices implement network switches that allow connecting strings of daisy chained devices to one single network port, as this would not make 802.1x port based authentication possible.\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Ensure that all ports on the device are isolated\",\n \"Ensure only one DHCP client is running\"\n ]\n },\n {\n \"name\": \"connection.target_ping\",\n \"description\": \"Device responds to ping\",\n \"expected_behavior\": \"The device under test responds to an ICMP echo (ping) request.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.ipaddr.ip_change\",\n \"description\": \"Device has accepted an IP address change\",\n \"expected_behavior\": \"If the lease expires before the client receiveds a DHCPACK, the client moves to INIT state, MUST immediately stop any other network processing and requires network initialization parameters as if the client were uninitialized. If the client then receives a DHCPACK allocating the client its previous network addres, the client SHOULD continue network processing. If the client is given a new network address, it MUST NOT continue using the previous network address and SHOULD notify the local users of the problem.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.ipaddr.dhcp_failover\",\n \"description\": \"Secondary DHCP server lease confirmed active in device\",\n \"expected_behavior\": \"\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"connection.ipv6_slaac\",\n \"description\": \"Device does not support IPv6 SLAAC\",\n \"expected_behavior\": \"The device under test complies with RFC4862 and forms a valid IPv6 SLAAC address\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Install a network manager that supports IPv6\",\n \"Disable DHCPv6\"\n ]\n },\n {\n \"name\": \"connection.ipv6_ping\",\n \"description\": \"No IPv6 SLAAC address found. Cannot ping\",\n \"expected_behavior\": \"The device responds to the ping as per RFC4443\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Enable ping response to IPv6 ICMP requests in network manager settings\",\n \"Create a firewall exception to allow ICMPv6 via LAN\"\n ]\n },\n {\n \"name\": \"security.tls.v1_2_server\",\n \"description\": \"TLS 1.2 certificate is invalid\",\n \"expected_behavior\": \"TLS 1.2 certificate is issued to the web browser client when accessed\",\n \"required_result\": \"Required if Applicable\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Enable TLS 1.2 support in the web server configuration\",\n \"Disable TLS 1.0 and 1.1\",\n \"Sign the certificate used by the web server\"\n ]\n },\n {\n \"name\": \"security.tls.v1_2_client\",\n \"description\": \"No outbound TLS connections were found\",\n \"expected_behavior\": \"The packet indicates a TLS connection with at least TLS 1.2 and support for ECDH and ECDSA ciphers\",\n \"required_result\": \"Required if Applicable\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"security.tls.v1_3_server\",\n \"description\": \"TLS 1.3 certificate is invalid\",\n \"expected_behavior\": \"TLS 1.3 certificate is issued to the web browser client when accessed\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n },\n {\n \"name\": \"security.tls.v1_3_client\",\n \"description\": \"No outbound TLS connections were found\",\n \"expected_behavior\": \"The packet indicates a TLS connection with at least TLS 1.3\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n },\n {\n \"name\": \"ntp.network.ntp_support\",\n \"description\": \"Device has not sent any NTP requests\",\n \"expected_behavior\": \"The device sends an NTPv4 request to the configured NTP server.\",\n \"required_result\": \"Required\",\n \"result\": \"Non-Compliant\",\n \"recommendations\": [\n \"Set the NTP version to v4 in the NTP client\",\n \"Install an NTP client that supports NTPv4\"\n ]\n },\n {\n \"name\": \"ntp.network.ntp_dhcp\",\n \"description\": \"Device has not sent any NTP requests\",\n \"expected_behavior\": \"Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)\",\n \"required_result\": \"Roadmap\",\n \"result\": \"Feature Not Detected\"\n },\n {\n \"name\": \"dns.network.hostname_resolution\",\n \"description\": \"DNS traffic detected from device\",\n \"expected_behavior\": \"The device sends DNS requests.\",\n \"required_result\": \"Required\",\n \"result\": \"Compliant\"\n },\n {\n \"name\": \"dns.network.from_dhcp\",\n \"description\": \"DNS traffic detected only to DHCP provided server\",\n \"expected_behavior\": \"The device sends DNS requests to the DNS server provided by the DHCP server\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n },\n {\n \"name\": \"dns.mdns\",\n \"description\": \"No MDNS traffic detected from the device\",\n \"expected_behavior\": \"Device may send MDNS requests\",\n \"required_result\": \"Informational\",\n \"result\": \"Informational\"\n }\n ]\n },\n \"report\": \"http://localhost:8000/report/Teltonika TRB140/2024-09-10T13:19:24\"\n }\n]"
},
{
"name": "No Test Reports (200)",
@@ -1348,7 +1348,7 @@
]
},
{
- "name": "Export",
+ "name": "Export Report",
"request": {
"method": "POST",
"header": [],
@@ -2305,7 +2305,6 @@
{
"key": "Content-Type",
"value": "application/json",
- "name": "Content-Type",
"description": "",
"type": "text"
}
@@ -2501,7 +2500,6 @@
{
"key": "Content-Type",
"value": "application/json",
- "name": "Content-Type",
"description": "",
"type": "text"
}
@@ -2578,7 +2576,6 @@
{
"key": "Content-Type",
"value": "application/json",
- "name": "Content-Type",
"description": "",
"type": "text"
}
@@ -2622,7 +2619,6 @@
{
"key": "Content-Type",
"value": "application/json",
- "name": "Content-Type",
"description": "",
"type": "text"
}
@@ -2666,7 +2662,6 @@
{
"key": "Content-Type",
"value": "application/json",
- "name": "Content-Type",
"description": "",
"type": "text"
}
@@ -2705,6 +2700,895 @@
},
"description": "Delete a root CA certificate"
},
+ "response": [
+ {
+ "name": "Delete Certificate (200)",
+ "originalRequest": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"name\": \"GTS Root R1\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/system/config/certs",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "system",
+ "config",
+ "certs"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"success\": \"Successfully deleted the certificate\"\n}"
+ },
+ {
+ "name": "Not Found (404)",
+ "originalRequest": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"name\": \"non-existing name\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/system/config/certs",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "system",
+ "config",
+ "certs"
+ ]
+ }
+ },
+ "status": "Not Found",
+ "code": 404,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"A certificate with that name could not be found\"\n}"
+ },
+ {
+ "name": "Invalid JSON (400)",
+ "originalRequest": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/system/config/certs",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "system",
+ "config",
+ "certs"
+ ]
+ }
+ },
+ "status": "Bad Request",
+ "code": 400,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"Received a bad request\"\n}"
+ }
+ ]
+ },
+ {
+ "name": "Get Profile Format",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profiles/format",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles",
+ "format"
+ ]
+ },
+ "description": "Obtain the current format of the risk assessment questionnaire"
+ },
+ "response": [
+ {
+ "name": "Get Profile Format (200)",
+ "originalRequest": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profiles/format",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles",
+ "format"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": ""
+ }
+ ],
+ "cookie": [],
+ "body": "[\n {\n \"question\": \"How will this device be used at Google?\",\n \"description\": \"Desribe your use case. Add links to user journey diagrams and TDD if available.\",\n \"type\": \"text-long\",\n \"validation\": {\n \"max\": \"512\",\n \"required\": true\n }\n },\n {\n \"question\": \"Is this device going to be managed by Google or a third party?\",\n \"description\": \"A manufacturer or supplier is considered third party in this case\",\n \"type\": \"select\",\n \"options\": [\n \"Google\",\n \"Third Party\"\n ],\n \"validation\": {\n \"required\": true\n }\n },\n {\n \"question\": \"Will the third-party device administrator be able to grant access to authorized Google personnel upon request?\",\n \"type\": \"select\",\n \"options\": [\n \"Yes\",\n \"No\",\n \"N/A\"\n ],\n \"default\": \"N/A\",\n \"validation\": {\n \"required\": true\n }\n },\n {\n \"category\": \"Data Transmission\",\n \"question\": \"Which of the following statements are true about this device?\",\n \"description\": \"This tells us about the types of data that are transmitted from this device and how the transmission is performed from a technical standpoint.\",\n \"type\": \"select-multiple\",\n \"options\": [\n \"PII/PHI, confidential/sensitive business data, Intellectual Property and Trade Secrets, Critical Infrastructure and Identity Assets to a domain outside Alphabet's ownership\",\n \"Data transmission occurs across less-trusted networks (e.g. the internet).\",\n \"A failure in data transmission would likely have a substantial negative impact (https://www.rra.rocks/docs/standard_levels#levels-definitions)\",\n \"A confidentiality breach during transmission would have a substantial negative impact\",\n \"The device does not encrypt data during transmission\",\n \"None of the above\"\n ],\n \"validation\": {\n \"required\": true\n }\n },\n {\n \"category\": \"Data Transmission\",\n \"question\": \"Does the network protocol assure server-to-client identity verification?\",\n \"type\": \"select\",\n \"options\": [\n \"Yes\",\n \"No\",\n \"I don't know\"\n ],\n \"validation\": {\n \"required\": true\n }\n },\n {\n \"category\": \"Remote Operation\",\n \"question\": \"Click the statements that best describe the characteristics of this device.\",\n \"description\": \"This tells us about how this device is managed remotely.\",\n \"type\": \"select-multiple\",\n \"options\": [\n \"PII/PHI, or confidential business data is accessible from the device without authentication\",\n \"Unrecoverable actions (e.g. disk wipe) can be performed remotely\",\n \"Authentication is not required for remote access\",\n \"The management interface is accessible from the public internet\",\n \"Static credentials are used for administration\",\n \"None of the above\"\n ],\n \"validation\": {\n \"required\": true\n }\n },\n {\n \"category\": \"Operating Environment\",\n \"question\": \"Are any of the following statements true about this device?\",\n \"description\": \"This informs us about what other systems and processes this device is a part of.\",\n \"type\": \"select-multiple\",\n \"options\": [\n \"The device monitors an environment for active risks to human life.\",\n \"The device is used to convey people, or critical property.\",\n \"The device controls robotics in human-accessible spaces.\",\n \"The device controls physical access systems.\",\n \"The device is involved in processes required by regulations, or compliance. (ex. privacy, security, safety regulations)\",\n \"The device's failure would cause faults in other high-criticality processes.\",\n \"None of the above\"\n ],\n \"validation\": {\n \"required\": true\n }\n },\n {\n \"question\": \"Comments\",\n \"description\": \"Anything else to share?\",\n \"type\": \"text-long\",\n \"validation\": {\n \"max\": \"512\"\n }\n }\n]"
+ }
+ ]
+ },
+ {
+ "name": "List Profiles",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ },
+ "description": "Get a list of risk assessment profiles saved by the user"
+ },
+ "response": [
+ {
+ "name": "List Profiles (200)",
+ "originalRequest": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": ""
+ }
+ ],
+ "cookie": [],
+ "body": "[\n {\n \"name\": \"New Profile\",\n \"version\": \"2.0\",\n \"created\": \"2024-10-08\",\n \"status\": \"Valid\",\n \"risk\": \"High\",\n \"questions\": [\n {\n \"question\": \"How will this device be used at Google?\",\n \"answer\": \"Yes\"\n },\n {\n \"question\": \"Is this device going to be managed by Google or a third party?\",\n \"answer\": \"Google\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Will the third-party device administrator be able to grant access to authorized Google personnel upon request?\",\n \"answer\": \"No\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Which of the following statements are true about this device?\",\n \"answer\": [\n 0,\n 1,\n 2\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Does the network protocol assure server-to-client identity verification?\",\n \"answer\": \"Yes\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Click the statements that best describe the characteristics of this device.\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Are any of the following statements true about this device?\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Comments\",\n \"answer\": \"\"\n }\n ]\n }\n]"
+ },
+ {
+ "name": "No Profiles (200)",
+ "originalRequest": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": ""
+ }
+ ],
+ "cookie": [],
+ "body": "[\n \n]"
+ }
+ ]
+ },
+ {
+ "name": "Export Profile",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profile/{profile_name}",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profile",
+ "{profile_name}"
+ ]
+ },
+ "description": "Get the PDF report for a specific device and timestamp"
+ },
+ "response": [
+ {
+ "name": "Get Profile No Device (200)",
+ "originalRequest": {
+ "method": "POST",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profile/Test",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profile",
+ "Test"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "text",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/pdf",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "profile.pdf"
+ },
+ {
+ "name": "Get Profile with Device (200))",
+ "originalRequest": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "type": "text"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\"mac_addr\": \"00:1e:42:35:73:c4\"}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profile/Test",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profile",
+ "Test"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "text",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/pdf",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "profile.pdf"
+ },
+ {
+ "name": "Profile Not Found (404)",
+ "originalRequest": {
+ "method": "POST",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profile/NonExistingProfile",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profile",
+ "NonExistingProfile"
+ ]
+ }
+ },
+ "status": "Not Found",
+ "code": 404,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"Profile could not be found\"\n}"
+ },
+ {
+ "name": "Device Not Found (404)",
+ "originalRequest": {
+ "method": "GET",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "type": "text"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\"mac_addr\": \"non_existing_mac_addr\"}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profile/Test",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profile",
+ "Test"
+ ]
+ }
+ },
+ "status": "Not Found",
+ "code": 404,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"A device with that mac address could not be found\"\n}"
+ },
+ {
+ "name": "Internal Server Error (500) Copy",
+ "originalRequest": {
+ "method": "POST",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8000/profile/Test",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profile",
+ "Test"
+ ]
+ }
+ },
+ "status": "Internal Server Error",
+ "code": 500,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"Error retrieving the profile PDF\"\n}"
+ }
+ ]
+ },
+ {
+ "name": "Update Profile",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"name\": \"Testing\",\n \"status\": \"Valid\",\n \"questions\": [\n {\n \"question\": \"What type of device is this?\",\n \"answer\": \"IoT Gateway\"\n },\n {\n \"question\": \"How will this device be used at Google?\",\n \"answer\": \"asdasd\"\n },\n {\n \"question\": \"Is this device going to be managed by Google or a third party?\",\n \"answer\": \"Google\"\n },\n {\n \"question\": \"Will the third-party device administrator be able to grant access to authorized Google personnel upon request?\",\n \"answer\": \"N/A\"\n },\n {\n \"question\": \"Are any of the following statements true about your device?\",\n \"answer\": [\n 3\n ]\n },\n {\n \"question\": \"Which of the following statements are true about this device?\",\n \"answer\": [\n 5\n ]\n },\n {\n \"question\": \"Does the network protocol assure server-to-client identity verification?\",\n \"answer\": \"Yes\"\n },\n {\n \"question\": \"Click the statements that best describe the characteristics of this device.\",\n \"answer\": [\n 5\n ]\n },\n {\n \"question\": \"Are any of the following statements true about this device?\",\n \"answer\": [\n 6\n ]\n },\n {\n \"question\": \"Comments\",\n \"answer\": \"\"\n }\n ]\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ },
+ "description": "Create or update a risk assessment questionnaire response"
+ },
+ "response": [
+ {
+ "name": "Update Profile (200)",
+ "originalRequest": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "\n{\n \"name\": \"New Profile\",\n \"rename\": \"Updated New Profile\",\n \"version\": \"2.0.1\",\n \"created\": \"2024-10-08\",\n \"status\": \"Valid\",\n \"risk\": \"High\",\n \"questions\": [\n {\n \"question\": \"How will this device be used at Google?\",\n \"answer\": \"Yes\"\n },\n {\n \"question\": \"Is this device going to be managed by Google or a third party?\",\n \"answer\": \"Google\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Will the third-party device administrator be able to grant access to authorized Google personnel upon request?\",\n \"answer\": \"No\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Which of the following statements are true about this device?\",\n \"answer\": [\n 0,\n 1,\n 2\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Does the network protocol assure server-to-client identity verification?\",\n \"answer\": \"Yes\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Click the statements that best describe the characteristics of this device.\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Are any of the following statements true about this device?\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Comments\",\n \"answer\": \"\"\n }\n ]\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"success\": \"Successfully updated that profile\"\n}"
+ },
+ {
+ "name": "Create Profile (201)",
+ "originalRequest": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "\n{\n \"name\": \"New Profile\",\n \"version\": \"2.0\",\n \"created\": \"2024-10-08\",\n \"status\": \"Valid\",\n \"risk\": \"High\",\n \"questions\": [\n {\n \"question\": \"How will this device be used at Google?\",\n \"answer\": \"Yes\"\n },\n {\n \"question\": \"Is this device going to be managed by Google or a third party?\",\n \"answer\": \"Google\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Will the third-party device administrator be able to grant access to authorized Google personnel upon request?\",\n \"answer\": \"No\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Which of the following statements are true about this device?\",\n \"answer\": [\n 0,\n 1,\n 2\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Does the network protocol assure server-to-client identity verification?\",\n \"answer\": \"Yes\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Click the statements that best describe the characteristics of this device.\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Are any of the following statements true about this device?\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Comments\",\n \"answer\": \"\"\n }\n ]\n}\n",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "Created",
+ "code": 201,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"success\": \"Successfully created a new profile\"\n}"
+ },
+ {
+ "name": "Invalid JSON (400)",
+ "originalRequest": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "Bad Request",
+ "code": 400,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"Invalid request received\"\n}"
+ },
+ {
+ "name": "Not Implemented (501)",
+ "originalRequest": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "[\n {\n \"name\": \"New Profile\",\n \"version\": \"2.0\",\n \"created\": \"2024-10-08\",\n \"status\": \"Valid\",\n \"risk\": \"High\",\n \"questions\": [\n {\n \"question\": \"How will this device be used at Google?\",\n \"answer\": \"Yes\"\n },\n {\n \"question\": \"Is this device going to be managed by Google or a third party?\",\n \"answer\": \"Google\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Will the third-party device administrator be able to grant access to authorized Google personnel upon request?\",\n \"answer\": \"No\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Which of the following statements are true about this device?\",\n \"answer\": [\n 0,\n 1,\n 2\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Does the network protocol assure server-to-client identity verification?\",\n \"answer\": \"Yes\",\n \"risk\": \"Limited\"\n },\n {\n \"question\": \"Click the statements that best describe the characteristics of this device.\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Are any of the following statements true about this device?\",\n \"answer\": [\n 0\n ],\n \"risk\": \"High\"\n },\n {\n \"question\": \"Comments\",\n \"answer\": \"\"\n }\n ]\n }\n]",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "Not Implemented",
+ "code": 501,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"Risk profiles are not available right now\"\n}"
+ }
+ ]
+ },
+ {
+ "name": "Delete Profile",
+ "request": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"name\": \"New Profile\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ },
+ "description": "Delete an existing risk assessment questionaire response"
+ },
+ "response": [
+ {
+ "name": "Delete Profile (200)",
+ "originalRequest": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"name\": \"New Profile\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "OK",
+ "code": 200,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"success\": \"Successfully deleted that profile\"\n}"
+ },
+ {
+ "name": "Not Found (404)",
+ "originalRequest": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"name\": \"non-existing profile\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "Not Found",
+ "code": 404,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"A profile with that name could not be found\"\n}"
+ },
+ {
+ "name": "Internal Serves Error (500)",
+ "originalRequest": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"name\": \"non-existing profile\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "Internal Server Error",
+ "code": 500,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"An error occurred whilst deleting that profile\"\n}"
+ },
+ {
+ "name": "Invalid JSON (400)",
+ "originalRequest": {
+ "method": "DELETE",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profiles",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profiles"
+ ]
+ }
+ },
+ "status": "Bad Request",
+ "code": 400,
+ "_postman_previewlanguage": "json",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "description": "",
+ "type": "text"
+ }
+ ],
+ "cookie": [],
+ "body": "{\n \"error\": \"Invalid request received\"\n}"
+ }
+ ]
+ },
+ {
+ "name": "http://localhost:8000/profile/Test",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "application/json",
+ "type": "text"
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\"mac_addr\": \"non_existing_mac_addr\"}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8000/profile/Test",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8000",
+ "path": [
+ "profile",
+ "Test"
+ ]
+ },
+ "description": "Delete a root CA certificate"
+ },
"response": [
{
"name": "Delete Certificate (200)",
diff --git a/docs/get_started.md b/docs/get_started.md
index 370f98a77..f0c39c284 100644
--- a/docs/get_started.md
+++ b/docs/get_started.md
@@ -73,7 +73,8 @@ Follow these steps to start Testrun:
1. Start Testrun with the command `sudo testrun`
- To run Testrun in network-only mode (without running any tests), use the `--net-only` option.
- To run Testrun with just one interface (connected to the device), use the `--single-intf` option.
-
+
+ **Note**: Tests that require an internet connection (e.g TLS client, DNS) will produce a non-compliant result.
## Test your device
diff --git a/framework/python/src/api/api.py b/framework/python/src/api/api.py
index 2bba5e62f..8febe03bb 100644
--- a/framework/python/src/api/api.py
+++ b/framework/python/src/api/api.py
@@ -43,6 +43,7 @@
DEVICE_ADDITIONAL_INFO_KEY = "additional_info"
DEVICES_PATH = "local/devices"
+PROFILES_PATH = "local/risk_profiles"
RESOURCES_PATH = "resources"
DEVICE_FOLDER_PATH = "devices"
@@ -133,6 +134,9 @@ def __init__(self, testrun):
self._router.add_api_route("/profiles",
self.delete_profile,
methods=["DELETE"])
+ self._router.add_api_route("/profile/{profile_name}",
+ self.export_profile,
+ methods=["POST"])
# Allow all origins to access the API
origins = ["*"]
@@ -278,7 +282,8 @@ async def start_testrun(self, request: Request, response: Response):
TestrunStatus.IN_PROGRESS,
TestrunStatus.WAITING_FOR_DEVICE,
TestrunStatus.MONITORING,
- TestrunStatus.VALIDATING
+ TestrunStatus.VALIDATING,
+ TestrunStatus.STARTING
]:
LOGGER.debug("Testrun is already running. Cannot start another instance")
@@ -341,7 +346,8 @@ async def stop_testrun(self, response: Response):
not in [TestrunStatus.IN_PROGRESS,
TestrunStatus.WAITING_FOR_DEVICE,
TestrunStatus.MONITORING,
- TestrunStatus.VALIDATING]):
+ TestrunStatus.VALIDATING,
+ TestrunStatus.STARTING]):
response.status_code = 404
return self._generate_msg(False, "Testrun is not currently running")
@@ -359,8 +365,9 @@ def shutdown(self, response: Response):
# Check that Testrun is not currently running
if (self._session.get_status()
not in [TestrunStatus.CANCELLED,
- TestrunStatus.COMPLIANT,
- TestrunStatus.NON_COMPLIANT,
+ TestrunStatus.PROCEED,
+ TestrunStatus.DO_NOT_PROCEED,
+ TestrunStatus.COMPLETE,
TestrunStatus.IDLE
]):
LOGGER.debug("Unable to shutdown Testrun as Testrun is in progress")
@@ -521,12 +528,14 @@ async def delete_device(self, request: Request, response: Response):
if (self._session.get_target_device() == device
and self._session.get_status()
not in [TestrunStatus.CANCELLED,
- TestrunStatus.COMPLIANT,
- TestrunStatus.NON_COMPLIANT
+ TestrunStatus.COMPLETE,
+ TestrunStatus.PROCEED,
+ TestrunStatus.DO_NOT_PROCEED
]):
+
response.status_code = 403
return self._generate_msg(
- False, "Cannot delete this device whilst " + "it is being tested")
+ False, "Cannot delete this device whilst it is being tested")
# Delete device
self._testrun.delete_device(device)
@@ -540,7 +549,7 @@ async def delete_device(self, request: Request, response: Response):
LOGGER.error(e)
response.status_code = 500
return self._generate_msg(
- False, "An error occured whilst deleting " + "the device")
+ False, "An error occured whilst deleting the device")
async def save_device(self, request: Request, response: Response):
LOGGER.debug("Received device post request")
@@ -644,8 +653,9 @@ async def edit_device(self, request: Request, response: Response):
if (self._session.get_target_device() == device
and self._session.get_status()
not in [TestrunStatus.CANCELLED,
- TestrunStatus.COMPLIANT,
- TestrunStatus.NON_COMPLIANT
+ TestrunStatus.COMPLETE,
+ TestrunStatus.PROCEED,
+ TestrunStatus.DO_NOT_PROCEED
]):
response.status_code = 403
return self._generate_msg(
@@ -926,6 +936,93 @@ async def delete_profile(self, request: Request, response: Response):
return self._generate_msg(True, "Successfully deleted that profile")
+ async def export_profile(self, request: Request, response: Response,
+ profile_name):
+
+ LOGGER.debug(f"Received get profile request for {profile_name}")
+
+ device = None
+
+ try:
+ req_raw = (await request.body()).decode("UTF-8")
+ req_json = json.loads(req_raw)
+
+ # Check if device mac_addr has been specified
+ if "mac_addr" in req_json and len(req_json.get("mac_addr")) > 0:
+ device_mac_addr = req_json.get("mac_addr")
+ device = self.get_session().get_device(device_mac_addr)
+
+ # If device is not found return 404
+ if device is None:
+ response.status_code = status.HTTP_404_NOT_FOUND
+ return self._generate_msg(
+ False, "A device with that mac address could not be found")
+
+ except JSONDecodeError:
+ # Device not specified
+ pass
+
+ # Retrieve the profile
+ profile = self._session.get_profile(profile_name)
+
+ # If the profile not found return 404
+ if profile is None:
+ LOGGER.info("Profile not found, returning 404")
+ response.status_code = 404
+ return self._generate_msg(False, "Profile could not be found")
+
+ # If device has been added into the body
+ if device:
+
+ try:
+
+ # Path where the PDF will be saved
+ profile_pdf_path = os.path.join(PROFILES_PATH, f"{profile_name}.pdf")
+
+ # Write the PDF content
+ with open(profile_pdf_path, "wb") as f:
+ f.write(profile.to_pdf(device).getvalue())
+
+ # Return the pdf file
+ if os.path.isfile(profile_pdf_path):
+ return FileResponse(profile_pdf_path)
+ else:
+ LOGGER.info("Profile could not be found, returning 404")
+ response.status_code = 404
+ return self._generate_msg(False, "Profile could not be found")
+
+ # Exceptions if the PDF creation fails
+ except Exception as e:
+ LOGGER.error(f"Error creating the profile PDF: {e}")
+ response.status_code = 500
+ return self._generate_msg(False, "Error retrieving the profile PDF")
+
+ # If device not added into the body
+ else:
+
+ try:
+
+ # Path where the PDF will be saved
+ profile_pdf_path = os.path.join(PROFILES_PATH, f"{profile_name}.pdf")
+
+ # Write the PDF content
+ with open(profile_pdf_path, "wb") as f:
+ f.write(profile.to_pdf_no_device().getvalue())
+
+ # Return the pdf file
+ if os.path.isfile(profile_pdf_path):
+ return FileResponse(profile_pdf_path)
+ else:
+ LOGGER.info("Profile could not be found, returning 404")
+ response.status_code = 404
+ return self._generate_msg(False, "Profile could not be found")
+
+ # Exceptions if the PDF creation fails
+ except Exception as e:
+ LOGGER.error(f"Error creating the profile PDF: {e}")
+ response.status_code = 500
+ return self._generate_msg(False, "Error retrieving the profile PDF")
+
# Certificates
def get_certs(self):
LOGGER.debug("Received certs list request")
diff --git a/framework/python/src/common/risk_profile.py b/framework/python/src/common/risk_profile.py
index 559117aec..fe613f69a 100644
--- a/framework/python/src/common/risk_profile.py
+++ b/framework/python/src/common/risk_profile.py
@@ -351,7 +351,7 @@ def to_html(self, device):
logo_img_b64 = base64.b64encode(f.read()).decode('utf-8')
self._device = self._format_device_profile(device)
- pages = self._generate_report_pages()
+ pages = self._generate_report_pages(device)
return self._template.render(
styles=self._template_styles,
manufacturer=self._device.manufacturer,
@@ -366,7 +366,33 @@ def to_html(self, device):
created_at=self.created.strftime('%d.%m.%Y')
)
- def _generate_report_pages(self):
+ def to_html_no_device(self):
+ """Returns the risk profile in HTML format without device info"""
+
+ high_risk_message = '''The device has been assessed to be high
+ risk due to the nature of the answers provided
+ about the device functionality.'''
+ limited_risk_message = '''The device has been assessed to be limited risk
+ due to the nature of the answers provided about
+ the device functionality.'''
+
+ with open(test_run_img_file, 'rb') as f:
+ logo_img_b64 = base64.b64encode(f.read()).decode('utf-8')
+
+ pages = self._generate_report_pages()
+ return self._template.render(
+ styles=self._template_styles,
+ logo=logo_img_b64,
+ risk=self.risk,
+ high_risk_message=high_risk_message,
+ limited_risk_message=limited_risk_message,
+ pages=pages,
+ total_pages=len(pages),
+ version=self.version,
+ created_at=self.created.strftime('%d.%m.%Y')
+ )
+
+ def _generate_report_pages(self, device=None):
# Text block heght
block_height = 18
@@ -391,8 +417,11 @@ def _generate_report_pages(self):
current_page = []
index = 1
- questions = deepcopy(self._device.additional_info)
- questions.extend(self.questions)
+ questions = deepcopy(self.questions)
+
+ if device:
+ questions = deepcopy(self._device.additional_info)
+ questions.extend(self.questions)
for question in questions:
@@ -456,6 +485,17 @@ def to_pdf(self, device):
HTML(string=html).write_pdf(pdf_bytes)
return pdf_bytes
+ def to_pdf_no_device(self):
+ """Returns the risk profile in PDF format without device info"""
+
+ # Resolve the data as html first
+ html = self.to_html_no_device()
+
+ # Convert HTML to PDF in memory using weasyprint
+ pdf_bytes = BytesIO()
+ HTML(string=html).write_pdf(pdf_bytes)
+ return pdf_bytes
+
# Adding risks to device profile questions
def _format_device_profile(self, device):
device_copy = deepcopy(device)
diff --git a/framework/python/src/common/statuses.py b/framework/python/src/common/statuses.py
index c7487868a..33516390e 100644
--- a/framework/python/src/common/statuses.py
+++ b/framework/python/src/common/statuses.py
@@ -15,18 +15,26 @@
class TestrunStatus:
+ """Statuses for overall testing"""
IDLE = "Idle"
+ STARTING = "Starting"
WAITING_FOR_DEVICE = "Waiting for Device"
MONITORING = "Monitoring"
IN_PROGRESS = "In Progress"
CANCELLED = "Cancelled"
- COMPLIANT = "Compliant"
- NON_COMPLIANT = "Non-Compliant"
STOPPING = "Stopping"
VALIDATING = "Validating Network"
+ COMPLETE = "Complete"
+ PROCEED = "Proceed"
+ DO_NOT_PROCEED = "Do Not Proceed"
+class TestrunResult:
+ """Statuses for the Testrun result"""
+ COMPLIANT = "Compliant"
+ NON_COMPLIANT = "Non-Compliant"
class TestResult:
+ """Statuses for test results"""
IN_PROGRESS = "In Progress"
COMPLIANT = "Compliant"
NON_COMPLIANT = "Non-Compliant"
diff --git a/framework/python/src/common/testreport.py b/framework/python/src/common/testreport.py
index 990a3427a..04d58a45c 100644
--- a/framework/python/src/common/testreport.py
+++ b/framework/python/src/common/testreport.py
@@ -16,14 +16,14 @@
from datetime import datetime
from weasyprint import HTML
from io import BytesIO
-from common import util
-from common.statuses import TestrunStatus
+from common import util, logger
+from common.statuses import TestrunStatus, TestrunResult
+from test_orc import test_pack
import base64
import os
from test_orc.test_case import TestCase
-from jinja2 import Environment, FileSystemLoader
+from jinja2 import Environment, FileSystemLoader, BaseLoader
from collections import OrderedDict
-import re
from bs4 import BeautifulSoup
@@ -32,7 +32,12 @@
TESTS_FIRST_PAGE = 11
TESTS_PER_PAGE = 20
TEST_REPORT_STYLES = 'test_report_styles.css'
-TEST_REPORT_TEMPLATE = 'test_report_template.html'
+TEMPLATES_FOLDER = 'report_templates'
+TEST_REPORT_TEMPLATE = 'report_template.html'
+ICON = 'icon.png'
+
+
+LOGGER = logger.get_logger('REPORT')
# Locate parent directory
current_dir = os.path.dirname(os.path.realpath(__file__))
@@ -45,35 +50,44 @@
report_resource_dir = os.path.join(root_dir, RESOURCES_DIR)
test_run_img_file = os.path.join(report_resource_dir, 'testrun.png')
-qualification_icon = os.path.join(report_resource_dir, 'qualification-icon.png')
-pilot_icon = os.path.join(report_resource_dir, 'pilot-icon.png')
class TestReport():
"""Represents a previous Testrun report."""
def __init__(self,
- status=TestrunStatus.NON_COMPLIANT,
+ result=TestrunResult.NON_COMPLIANT,
started=None,
finished=None,
total_tests=0):
self._device = {}
self._mac_addr = None
- self._status: str = status
+ self._status: TestrunStatus = TestrunStatus.COMPLETE
+ self._result: TestrunResult = result
self._started = started
self._finished = finished
self._total_tests = total_tests
self._results = []
self._module_reports = []
+ self._module_templates = []
self._report_url = ''
self._cur_page = 0
+ def update_device_profile(self, additional_info):
+ self._device['device_profile'] = additional_info
+
def add_module_reports(self, module_reports):
self._module_reports = module_reports
+ def add_module_templates(self, module_templates):
+ self._module_templates = module_templates
+
def get_status(self):
return self._status
+ def get_result(self):
+ return self._result
+
def get_started(self):
return self._started
@@ -109,6 +123,7 @@ def to_json(self):
report_json['mac_addr'] = self._mac_addr
report_json['device'] = self._device
report_json['status'] = self._status
+ report_json['result'] = self._result
report_json['started'] = self._started.strftime(DATE_TIME_FORMAT)
report_json['finished'] = self._finished.strftime(DATE_TIME_FORMAT)
@@ -162,6 +177,10 @@ def from_json(self, json_file):
self._device['device_profile'] = json_file['device']['additional_info']
self._status = json_file['status']
+
+ if 'result' in json_file:
+ self._result = json_file['result']
+
self._started = datetime.strptime(json_file['started'], DATE_TIME_FORMAT)
self._finished = datetime.strptime(json_file['finished'], DATE_TIME_FORMAT)
@@ -201,9 +220,22 @@ def to_pdf(self):
def to_html(self):
+ # Obtain test pack
+ current_test_pack = test_pack.TestPack.get_test_pack(
+ self._device['test_pack'])
+ template_folder = os.path.join(current_test_pack.path,
+ TEMPLATES_FOLDER)
# Jinja template
- template_env = Environment(loader=FileSystemLoader(report_resource_dir))
+ template_env = Environment(
+ loader=FileSystemLoader(
+ template_folder
+ ),
+ trim_blocks=True,
+ lstrip_blocks=True
+ )
template = template_env.get_template(TEST_REPORT_TEMPLATE)
+
+ # Report styles
with open(os.path.join(report_resource_dir,
TEST_REPORT_STYLES),
'r',
@@ -215,13 +247,11 @@ def to_html(self):
with open(test_run_img_file, 'rb') as f:
logo = base64.b64encode(f.read()).decode('utf-8')
- json_data=self.to_json()
+ # Icon
+ with open(os.path.join(template_folder, ICON), 'rb') as f:
+ icon = base64.b64encode(f.read()).decode('utf-8')
- # Icons
- with open(qualification_icon, 'rb') as f:
- icon_qualification = base64.b64encode(f.read()).decode('utf-8')
- with open(pilot_icon, 'rb') as f:
- icon_pilot = base64.b64encode(f.read()).decode('utf-8')
+ json_data=self.to_json()
# Convert the timestamp strings to datetime objects
start_time = datetime.strptime(json_data['started'], '%Y-%m-%d %H:%M:%S')
@@ -237,25 +267,25 @@ def to_html(self):
successful_tests += 1
# Obtain the steps to resolve
- steps_to_resolve = self._get_steps_to_resolve(json_data)
-
- # Obtain optional recommendations
- optional_steps_to_resolve = self._get_optional_steps_to_resolve(json_data)
+ logic = current_test_pack.get_logic()
+ steps_to_resolve_ = logic.get_steps_to_resolve(json_data)
- module_reports = self._get_module_pages()
+ module_reports = self._module_reports
+ env_module = Environment(loader=BaseLoader())
pages_num = self._pages_num(json_data)
- total_pages = pages_num + len(module_reports) + 1
- if len(steps_to_resolve) > 0:
- total_pages += 1
- if (len(optional_steps_to_resolve) > 0
- and json_data['device']['test_pack'] == 'Pilot Assessment'
- ):
- total_pages += 1
-
- return template.render(styles=styles,
+ module_templates = [
+ env_module.from_string(s).render(
+ name=current_test_pack.name,
+ device=json_data['device'],
+ logo=logo,
+ icon=icon,
+ version=self._version,
+ ) for s in self._module_templates
+ ]
+
+ return self._add_page_counter(template.render(styles=styles,
logo=logo,
- icon_qualification=icon_qualification,
- icon_pilot=icon_pilot,
+ icon=icon,
version=self._version,
json_data=json_data,
device=json_data['device'],
@@ -265,14 +295,22 @@ def to_html(self):
successful_tests=successful_tests,
total_tests=self._total_tests,
test_results=json_data['tests']['results'],
- steps_to_resolve=steps_to_resolve,
- optional_steps_to_resolve=optional_steps_to_resolve,
+ steps_to_resolve=steps_to_resolve_,
module_reports=module_reports,
pages_num=pages_num,
- total_pages=total_pages,
tests_first_page=TESTS_FIRST_PAGE,
tests_per_page=TESTS_PER_PAGE,
- )
+ module_templates=module_templates
+ ))
+
+ def _add_page_counter(self, html):
+ # Add page nums and total page
+ soup = BeautifulSoup(html, features='html5lib')
+ page_index_divs = soup.find_all('div', class_='page-index')
+ total_pages = len(page_index_divs)
+ for index, div in enumerate(page_index_divs):
+ div.string = f'Page {index+1}/{total_pages}'
+ return str(soup)
def _pages_num(self, json_data):
@@ -312,136 +350,3 @@ def _device_modules(self, device):
reverse=True)
)
return sorted_modules
-
- def _get_steps_to_resolve(self, json_data):
- tests_with_recommendations = []
-
- # Collect all tests with recommendations
- for test in json_data['tests']['results']:
- if 'recommendations' in test:
- tests_with_recommendations.append(test)
-
- return tests_with_recommendations
-
- def _get_optional_steps_to_resolve(self, json_data):
- tests_with_recommendations = []
-
- # Collect all tests with recommendations
- for test in json_data['tests']['results']:
- if 'optional_recommendations' in test:
- tests_with_recommendations.append(test)
-
- return tests_with_recommendations
-
-
- def _split_module_report_to_pages(self, reports):
- """Split report to pages by headers"""
- reports_transformed = []
-
- for report in reports:
- if len(re.findall('
1:
- indices = []
- index = report.find('= content_max_size:
- str_el = ''
- if current_size > (content_max_size - 85 - module_summary_padding):
- rows = el.findChildren('tr', recursive=True)
- table_header = str(rows.pop(0))
- table_1 = table_2 = f'''
-
- {table_header} '''
- rows_count = (content_max_size - 85 - module_summary_padding) // 42
- table_1 += ''.join(map(str, rows[:rows_count-1]))
- table_1 += '
'
- table_2 += ''.join(map(str, rows[rows_count-1:]))
- table_2 += '
'
- page_content += table_1
- reports.append(page_content)
- page_content = table_2
- current_size = len(rows[rows_count:]) * 42
- else:
- if el.name == 'table':
- el_header = children[index-1]
- if el_header.name.startswith('h'):
- page_content = ''.join(page_content.rsplit(str(el_header), 1))
- str_el = str(el_header) + str(el)
- content_size = current_size + 50
- else:
- str_el = str(el)
- content_size = current_size
- reports.append(page_content)
- page_content = str_el
- else:
- page_content += str(el)
- content_size += current_size
- reports.append(page_content)
- return reports
diff --git a/framework/python/src/core/session.py b/framework/python/src/core/session.py
index 17d583219..baa7db056 100644
--- a/framework/python/src/core/session.py
+++ b/framework/python/src/core/session.py
@@ -20,7 +20,7 @@
from fastapi.encoders import jsonable_encoder
from common import util, logger, mqtt
from common.risk_profile import RiskProfile
-from common.statuses import TestrunStatus, TestResult
+from common.statuses import TestrunStatus, TestResult, TestrunResult
from net_orc.ip_control import IPControl
# Certificate dependencies
@@ -85,6 +85,7 @@ def __init__(self, root_dir):
self._root_dir = root_dir
self._status = TestrunStatus.IDLE
+ self._result = None
self._description = None
# Target test device
@@ -100,6 +101,9 @@ def __init__(self, root_dir):
# All historical reports
self._module_reports = []
+ # Module report templates
+ self._module_templates = []
+
# Parameters specified when starting Testrun
self._runtime_params = []
@@ -156,7 +160,7 @@ def __init__(self, root_dir):
def start(self):
self.reset()
- self._status = TestrunStatus.WAITING_FOR_DEVICE
+ self._status = TestrunStatus.STARTING
self._started = datetime.datetime.now()
def get_started(self):
@@ -383,12 +387,18 @@ def get_ipv4_subnet(self):
def get_ipv6_subnet(self):
return self._ipv6_subnet
- def get_status(self):
+ def get_status(self) -> TestrunStatus:
return self._status
- def set_status(self, status):
+ def set_status(self, status: TestrunStatus):
self._status = status
+ def get_result(self) -> TestrunResult:
+ return self._result
+
+ def set_result(self, result: TestrunResult):
+ self._result = result
+
def set_description(self, desc: str):
self._description = desc
@@ -398,6 +408,9 @@ def get_test_results(self):
def get_module_reports(self):
return self._module_reports
+ def get_module_templates(self):
+ return self._module_templates
+
def get_report_tests(self):
"""Returns the current test results in JSON-friendly format
(in Python dictionary)"""
@@ -467,6 +480,9 @@ def set_test_result_error(self, result, description=None):
def add_module_report(self, module_report):
self._module_reports.append(module_report)
+ def add_module_template(self, module_template):
+ self._module_templates.append(module_template)
+
def get_all_reports(self):
reports = []
@@ -539,6 +555,9 @@ def _load_profiles(self):
for risk_profile_file in os.listdir(
os.path.join(self._root_dir, PROFILES_DIR)):
+ if not risk_profile_file.endswith('.json'):
+ continue
+
LOGGER.debug(f'Discovered profile {risk_profile_file}')
# Open the risk profile file
@@ -660,7 +679,7 @@ def _remove_invalid_questions(self, questions):
valid_questions.append(question)
else:
- LOGGER.debug(f'Removed unrecognised question: {question["question"]}')
+ LOGGER.debug(f'Removed unrecognised question: {question["question"]}') # pylint: disable=W1405
# Return the list of valid questions
return valid_questions
@@ -683,6 +702,15 @@ def validate_profile_json(self, profile_json):
LOGGER.error('Name field left empty')
return False
+ # Check if profile name has special characters
+ for field in ['name', 'rename']:
+ profile_name = profile_json.get(field)
+ if profile_name:
+ for char in profile_name:
+ if char in r"\<>?/:;@''][=^":
+ LOGGER.error('Profile name should not contain special characters')
+ return False
+
# Error handling if 'questions' not in request
if 'questions' not in profile_json and valid:
LOGGER.error('Missing "questions" field in profile')
@@ -706,7 +734,7 @@ def validate_profile_json(self, profile_json):
question.get('question'))
if format_q is None:
- LOGGER.error(f'Unrecognised question: {question.get("question")}')
+ LOGGER.error(f'Unrecognised question: {question.get("question")}') # pylint: disable=W1405
# Just ignore additional questions
continue
@@ -786,11 +814,13 @@ def delete_profile(self, profile):
def reset(self):
self.set_status(TestrunStatus.IDLE)
+ self.set_result(None)
self.set_description(None)
self.set_target_device(None)
self._report_url = None
self._total_tests = 0
self._module_reports = []
+ self._module_templates = []
self._results = []
self._started = None
self._finished = None
@@ -816,6 +846,9 @@ def to_json(self):
'tests': results
}
+ if self.get_result() is not None:
+ session_json['result'] = self.get_result()
+
if self._report_url is not None:
session_json['report'] = self.get_report_url()
diff --git a/framework/python/src/core/testrun.py b/framework/python/src/core/testrun.py
index 5d4e78e9c..f3fe33c80 100644
--- a/framework/python/src/core/testrun.py
+++ b/framework/python/src/core/testrun.py
@@ -22,6 +22,8 @@
import signal
import sys
import time
+import docker.errors
+
from common import logger, util, mqtt
from common.device import Device
from common.testreport import TestReport
@@ -32,8 +34,6 @@
from net_orc import network_orchestrator as net_orc
from test_orc import test_orchestrator as test_orc
-from docker.errors import ImageNotFound
-
LOGGER = logger.get_logger('testrun')
DEFAULT_CONFIG_FILE = 'local/system.json'
@@ -375,6 +375,7 @@ def start(self):
self._device_stable, [NetworkEvent.DEVICE_STABLE])
self.get_net_orc().start_listener()
+ self.get_session().set_status(TestrunStatus.WAITING_FOR_DEVICE)
LOGGER.info('Waiting for devices on the network...')
# Keep application running until stopped
@@ -463,6 +464,8 @@ def _device_discovered(self, mac_addr):
if device is not None:
if mac_addr != device.mac_addr:
+ LOGGER.info(f'Found device with mac addr: {mac_addr} but was ignored')
+ LOGGER.info(f'Expected device mac address is {device.mac_addr}')
# Ignore discovered device because it is not the target device
return
else:
@@ -485,10 +488,7 @@ def _device_stable(self, mac_addr):
LOGGER.info(f'Device with mac address {mac_addr} is ready for testing.')
self._set_status(TestrunStatus.IN_PROGRESS)
- result = self._test_orc.run_test_modules()
-
- if result is not None:
- self._set_status(result)
+ self._test_orc.run_test_modules()
self._stop_network()
@@ -513,7 +513,7 @@ def start_ui(self):
hostname='testrun.io',
detach=True,
ports={'80': 8080})
- except ImageNotFound as ie:
+ except docker.errors.ImageNotFound as ie:
LOGGER.error('An error occured whilst starting the UI. ' +
'Please investigate and try again.')
LOGGER.error(ie)
@@ -529,6 +529,11 @@ def _stop_ui(self):
container = client.containers.get('tr-ui')
if container is not None:
container.kill()
+ # If the container has been started without auto-remove flag remove it
+ try:
+ container.remove()
+ except docker.errors.APIError:
+ pass
except docker.errors.NotFound:
pass
@@ -549,7 +554,7 @@ def start_ws(self):
'9001': 9001,
'1883': 1883
})
- except ImageNotFound as ie:
+ except docker.errors.ImageNotFound as ie:
LOGGER.error('An error occured whilst starting the websockets server. ' +
'Please investigate and try again.')
LOGGER.error(ie)
@@ -562,5 +567,11 @@ def _stop_ws(self):
container = client.containers.get('tr-ws')
if container is not None:
container.kill()
+ # If the container has been started without auto-remove flag remove it
+ try:
+ container.remove()
+ except docker.errors.APIError:
+ pass
+
except docker.errors.NotFound:
pass
diff --git a/framework/python/src/net_orc/network_orchestrator.py b/framework/python/src/net_orc/network_orchestrator.py
index 37858c4e1..25e036ef7 100644
--- a/framework/python/src/net_orc/network_orchestrator.py
+++ b/framework/python/src/net_orc/network_orchestrator.py
@@ -713,7 +713,8 @@ def internet_conn_checker(self, mqtt_client: mqtt.MQTT, topic: str):
if self.get_session().get_status() not in [
TestrunStatus.WAITING_FOR_DEVICE,
TestrunStatus.MONITORING,
- TestrunStatus.IN_PROGRESS
+ TestrunStatus.IN_PROGRESS,
+ TestrunStatus.STARTING
]:
message['connection'] = None
diff --git a/framework/python/src/test_orc/test_orchestrator.py b/framework/python/src/test_orc/test_orchestrator.py
index 8e275b2cf..4334349c6 100644
--- a/framework/python/src/test_orc/test_orchestrator.py
+++ b/framework/python/src/test_orc/test_orchestrator.py
@@ -22,7 +22,7 @@
from datetime import datetime
from common import logger, util
from common.testreport import TestReport
-from common.statuses import TestrunStatus, TestResult
+from common.statuses import TestrunStatus, TestrunResult, TestResult
from core.docker.test_docker_module import TestModule
from test_orc.test_case import TestCase
from test_orc.test_pack import TestPack
@@ -37,6 +37,8 @@
RUNTIME_TEST_DIR = os.path.join(RUNTIME_DIR, "test")
TEST_PACKS_DIR = os.path.join(RESOURCES_DIR, "test_packs")
+TEST_PACK_CONFIG_FILE = "config.json"
+TEST_PACK_LOGIC_FILE = "test_pack.py"
TEST_MODULES_DIR = "modules/test"
MODULE_CONFIG = "conf/module_config.json"
@@ -177,6 +179,7 @@ def run_test_modules(self):
generated_report_json = self._generate_report()
report.from_json(generated_report_json)
report.add_module_reports(self.get_session().get_module_reports())
+ report.add_module_templates(self.get_session().get_module_templates())
device.add_report(report)
self._write_reports(report)
@@ -189,13 +192,17 @@ def run_test_modules(self):
# Default message is empty (better than an error message).
# This should never be shown
message: str = ""
- if report.get_status() == TestrunStatus.COMPLIANT:
+ if report.get_result() == TestrunResult.COMPLIANT:
message = test_pack.get_message("compliant_description")
- elif report.get_status() == TestrunStatus.NON_COMPLIANT:
+ elif report.get_result() == TestrunResult.NON_COMPLIANT:
message = test_pack.get_message("non_compliant_description")
self.get_session().set_description(message)
+ # Set result and status at the end
+ self.get_session().set_result(report.get_result())
+ self.get_session().set_status(report.get_status())
+
# Move testing output from runtime to local device folder
self._timestamp_results(device)
@@ -204,8 +211,6 @@ def run_test_modules(self):
LOGGER.debug("Old test results cleaned")
- return report.get_status()
-
def _write_reports(self, test_report):
out_dir = os.path.join(
@@ -230,44 +235,40 @@ def _write_reports(self, test_report):
def _generate_report(self):
+ device = self.get_session().get_target_device()
+ test_pack_name = device.test_pack
+ test_pack = self.get_test_pack(test_pack_name)
+
report = {}
report["testrun"] = {"version": self.get_session().get_version()}
- report["mac_addr"] = self.get_session().get_target_device().mac_addr
- report["device"] = self.get_session().get_target_device().to_dict()
+ report["mac_addr"] = device.mac_addr
+ report["device"] = device.to_dict()
report["started"] = self.get_session().get_started().strftime(
"%Y-%m-%d %H:%M:%S")
report["finished"] = self.get_session().get_finished().strftime(
"%Y-%m-%d %H:%M:%S")
- report["status"] = self._calculate_result()
+
+ # Update the result
+ result = test_pack.get_logic().calculate_result(
+ self.get_session().get_test_results())
+ report["result"] = result
+
+ # Update the status
+ status = test_pack.get_logic().calculate_status(
+ result,
+ self.get_session().get_test_results())
+ report["status"] = status
+
report["tests"] = self.get_session().get_report_tests()
report["report"] = (
self._api_url + "/" + SAVED_DEVICE_REPORTS.replace(
"{device_folder}",
- self.get_session().get_target_device().device_folder) +
+ device.device_folder) +
self.get_session().get_started().strftime("%Y-%m-%dT%H:%M:%S"))
return report
- def _calculate_result(self):
- result = TestResult.COMPLIANT
- for test_result in self.get_session().get_test_results():
-
- # Check Required tests
- if (test_result.required_result.lower() == "required"
- and test_result.result not in [
- TestResult.COMPLIANT,
- TestResult.ERROR
- ]):
- result = TestResult.NON_COMPLIANT
-
- # Check Required if Applicable tests
- elif (test_result.required_result.lower() == "required if applicable"
- and test_result.result == TestResult.NON_COMPLIANT):
- result = TestResult.NON_COMPLIANT
-
- return result
-
def _cleanup_old_test_results(self, device):
if device.max_device_reports is not None:
@@ -348,7 +349,7 @@ def _timestamp_results(self, device):
return completed_results_dir
- def zip_results(self, device, timestamp, profile):
+ def zip_results(self, device, timestamp: str, profile):
try:
LOGGER.debug("Archiving test results")
@@ -357,6 +358,50 @@ def zip_results(self, device, timestamp, profile):
LOCAL_DEVICE_REPORTS.replace("{device_folder}", device.device_folder),
timestamp)
+ # Report file path
+ report_path = os.path.join(
+ LOCAL_DEVICE_REPORTS.replace("{device_folder}", device.device_folder),
+ timestamp, "test", device.mac_addr.replace(":", ""))
+
+ # Parse string timestamp
+ date_timestamp: datetime.datetime = datetime.strptime(
+ timestamp, "%Y-%m-%dT%H:%M:%S")
+
+ # Find the report
+ test_report = None
+ for report in device.get_reports():
+ if report.get_started() == date_timestamp:
+ test_report = report
+
+ # This should not happen as the timestamp is checked in api.py first
+ if test_report is None:
+ return None
+
+ # Copy the original report for comparison
+ original_report = copy.deepcopy(test_report)
+
+ # Update the report with 'additional_info' field
+ test_report.update_device_profile(device.additional_info)
+
+ # Overwrite report only if additional_info has been updated
+ if original_report.to_json() != test_report.to_json():
+
+ # Write the json report
+ with open(os.path.join(report_path, "report.json"),
+ "w",
+ encoding="utf-8") as f:
+ json.dump(test_report.to_json(), f, indent=2)
+
+ # Write the html report
+ with open(os.path.join(report_path, "report.html"),
+ "w",
+ encoding="utf-8") as f:
+ f.write(test_report.to_html())
+
+ # Write the pdf report
+ with open(os.path.join(report_path, "report.pdf"), "wb") as f:
+ f.write(test_report.to_pdf().getvalue())
+
# Define temp directory to store files before zipping
results_dir = os.path.join(f"/tmp/testrun/{time.time()}")
@@ -487,6 +532,20 @@ def _run_test_module(self, module):
if time.time() > test_module_timeout:
LOGGER.error("Module timeout exceeded, killing module: " + module.name)
module.stop(kill=True)
+
+ # Update the test description for the tests
+ for test in module.tests:
+
+ # Copy the test so we don't alter the source
+ test_copy = copy.deepcopy(test)
+
+ # Update test
+ test_copy.result = TestResult.ERROR
+ test_copy.description = (
+ "Module timeout exceeded. Try increasing the timeout value."
+ )
+ self.get_session().add_test_result(test_copy)
+
break
# Save all container logs to file
@@ -511,14 +570,13 @@ def _run_test_module(self, module):
for test_result in module_results:
# Convert dict from json into TestCase object
- test_case = TestCase(
- name=test_result["name"],
- result=test_result["result"],
- description=test_result["description"])
+ test_case = TestCase(name=test_result["name"],
+ result=test_result["result"],
+ description=test_result["description"])
# Add steps to resolve if test is non-compliant
- if (test_case.result == TestResult.NON_COMPLIANT and
- "recommendations" in test_result):
+ if (test_case.result == TestResult.NON_COMPLIANT
+ and "recommendations" in test_result):
test_case.recommendations = test_result["recommendations"]
else:
test_case.recommendations = []
@@ -549,8 +607,17 @@ def _run_test_module(self, module):
self.get_session().add_module_report(module_report)
except (FileNotFoundError, PermissionError):
LOGGER.debug("Test module did not produce a html module report")
+ # Get the Jinja report
+ jinja_file = f"{module.container_runtime_dir}/{module.name}_report.j2.html"
+ try:
+ with open(jinja_file, "r", encoding="utf-8") as f:
+ module_template = f.read()
+ LOGGER.debug(f"Adding module template for module {module.name}")
+ self.get_session().add_module_template(module_template)
+ except (FileNotFoundError, PermissionError):
+ LOGGER.debug("Test module did not produce a module template")
- LOGGER.info(f"Test module {module.name} has finished")
+ # LOGGER.info(f"Test module {module.name} has finished")
def _get_container_logs(self, log_stream):
"""Resolve all current log data in the containers log_stream
@@ -595,23 +662,7 @@ def _get_module_container(self, module):
def _load_test_packs(self):
- for test_pack_file in os.listdir(TEST_PACKS_DIR):
-
- LOGGER.debug(f"Loading test pack {test_pack_file}")
-
- with open(os.path.join(
- self._root_path,
- TEST_PACKS_DIR,
- test_pack_file), encoding="utf-8") as f:
- test_pack_json = json.load(f)
-
- test_pack: TestPack = TestPack(
- name = test_pack_json["name"],
- tests = test_pack_json["tests"],
- language = test_pack_json["language"]
- )
-
- self._test_packs.append(test_pack)
+ self._test_packs = TestPack.get_test_packs()
def _load_test_modules(self):
"""Load network modules from module_config.json."""
@@ -626,6 +677,12 @@ def _load_test_modules(self):
# corrupted during DHCP changes in the conn module
if "protocol" in module_dirs:
module_dirs.insert(0, module_dirs.pop(module_dirs.index("protocol")))
+ # Check if the directory services exists and move it higher in the index
+ # so it always runs before connection. Connection may cause too many
+ # DHCP changes causing nmap to use wrong IP during scan
+ if "services" in module_dirs and "conn" in module_dirs:
+ module_dirs.insert(module_dirs.index("conn"),
+ module_dirs.pop(module_dirs.index("services")))
for module_dir in module_dirs:
@@ -656,9 +713,7 @@ def _load_test_module(self, module_dir):
module_conf_file = os.path.join(self._root_path, modules_dir, module_dir,
MODULE_CONFIG)
- module = TestModule(module_conf_file,
- self,
- self.get_session(),
+ module = TestModule(module_conf_file, self, self.get_session(),
extra_hosts)
if module.depends_on is not None:
self._load_test_module(module.depends_on)
@@ -670,10 +725,7 @@ def get_test_packs(self) -> List[TestPack]:
return self._test_packs
def get_test_pack(self, name: str) -> TestPack:
- for test_pack in self._test_packs:
- if test_pack.name.lower() == name.lower():
- return test_pack
- return None
+ return TestPack.get_test_pack(name, self._test_packs)
def _stop_modules(self, kill=False):
LOGGER.info("Stopping test modules")
@@ -719,6 +771,5 @@ def _set_test_modules_error(self, current_test):
start_idx = current_test if i == self._current_module else 0
for j in range(start_idx, len(self._test_modules_running[i].tests)):
self.get_session().set_test_result_error(
- self._test_modules_running[i].tests[j],
- "Test did not run, the device was disconnected"
- )
+ self._test_modules_running[i].tests[j],
+ "Test did not run, the device was disconnected")
diff --git a/framework/python/src/test_orc/test_pack.py b/framework/python/src/test_orc/test_pack.py
index a2e7c5f97..eb9c852c2 100644
--- a/framework/python/src/test_orc/test_pack.py
+++ b/framework/python/src/test_orc/test_pack.py
@@ -13,9 +13,20 @@
# limitations under the License.
"""Represents a testing pack."""
+from types import ModuleType
from typing import List, Dict
from dataclasses import dataclass, field
from collections import defaultdict
+import os
+import sys
+import json
+import importlib
+
+RESOURCES_DIR = "resources"
+
+TEST_PACKS_DIR = os.path.join(RESOURCES_DIR, "test_packs")
+TEST_PACK_CONFIG_FILE = "config.json"
+TEST_PACK_LOGIC_FILE = "test_pack.py"
@dataclass
@@ -26,6 +37,8 @@ class TestPack: # pylint: disable=too-few-public-methods,too-many-instance-attr
description: str = ""
tests: List[dict] = field(default_factory=lambda: [])
language: Dict = field(default_factory=lambda: defaultdict(dict))
+ pack_logic: ModuleType = None
+ path: str = ""
def get_test(self, test_name: str) -> str:
"""Get details of a test from the test pack"""
@@ -44,6 +57,9 @@ def get_required_result(self, test_name: str) -> str:
return "Informational"
+ def get_logic(self):
+ return self.pack_logic
+
def get_message(self, name: str) -> str:
if name in self.language:
return self.language[name]
@@ -56,3 +72,62 @@ def to_dict(self):
"tests": self.tests,
"language": self.language
}
+
+ @staticmethod
+ def load_logic(source, module_name=None):
+ """Reads file source and loads it as a module"""
+
+ spec = importlib.util.spec_from_file_location(module_name, source)
+ module = importlib.util.module_from_spec(spec)
+
+ # Add the module to sys.modules
+ sys.modules[module_name] = module
+
+ # Execute the module
+ spec.loader.exec_module(module)
+
+ return module
+
+ @staticmethod
+ def get_test_packs() -> List["TestPack"]:
+
+ root_path = os.path.dirname(
+ os.path.dirname(
+ os.path.dirname(
+ os.path.dirname(os.path.dirname(os.path.realpath(__file__))))))
+ test_packs = []
+
+ for test_pack_folder in os.listdir(TEST_PACKS_DIR):
+ test_pack_path = os.path.join(
+ root_path,
+ TEST_PACKS_DIR,
+ test_pack_folder
+ )
+
+ with open(os.path.join(
+ test_pack_path,
+ TEST_PACK_CONFIG_FILE), encoding="utf-8") as f:
+ test_pack_json = json.load(f)
+
+ test_pack: TestPack = TestPack(
+ name = test_pack_json["name"],
+ tests = test_pack_json["tests"],
+ language = test_pack_json["language"],
+ pack_logic = TestPack.load_logic(
+ os.path.join(test_pack_path, TEST_PACK_LOGIC_FILE),
+ "test_pack_" + test_pack_folder + "_logic"
+ ),
+ path = test_pack_path
+ )
+ test_packs.append(test_pack)
+
+ return test_packs
+
+ @staticmethod
+ def get_test_pack(name: str, test_packs: List["TestPack"]=None) -> "TestPack":
+ if test_packs is None:
+ test_packs = TestPack.get_test_packs()
+ for test_pack in test_packs:
+ if test_pack.name.lower() == name.lower():
+ return test_pack
+ return None
diff --git a/framework/requirements.txt b/framework/requirements.txt
index 6299ef6d4..b5726aca2 100644
--- a/framework/requirements.txt
+++ b/framework/requirements.txt
@@ -28,7 +28,7 @@ responses==0.25.3
markdown==3.5.2
# Requirements for the session
-cryptography==44.0.0
+cryptography==44.0.1
pytz==2024.1
# Requirements for the risk profile
@@ -41,5 +41,5 @@ paho-mqtt==2.1.0
APScheduler==3.10.4
# Requirements for reports generation
-Jinja2==3.1.4
+Jinja2==3.1.5
beautifulsoup4==4.12.3
diff --git a/make/DEBIAN/control b/make/DEBIAN/control
index d4024828e..2a0235082 100644
--- a/make/DEBIAN/control
+++ b/make/DEBIAN/control
@@ -1,5 +1,5 @@
Package: Testrun
-Version: 2.1
+Version: 2.1.1
Architecture: amd64
Maintainer: Google
Homepage: https://github.com/google/testrun
diff --git a/modules/test/base/base.Dockerfile b/modules/test/base/base.Dockerfile
index 253270ea9..7a82301a7 100644
--- a/modules/test/base/base.Dockerfile
+++ b/modules/test/base/base.Dockerfile
@@ -80,5 +80,13 @@ COPY --from=builder /usr/local/etc/oui.txt /usr/local/etc/oui.txt
# Activate the virtual environment by setting the PATH
ENV PATH="/opt/venv/bin:$PATH"
+# Common resource folder
+ENV REPORT_TEMPLATE_PATH=/testrun/resources
+# Jinja base template
+ENV BASE_TEMPLATE_FILE=module_report_base.jinja2
+
+# Copy base template
+COPY resources/report/$BASE_TEMPLATE_FILE $REPORT_TEMPLATE_PATH/
+
# Start the test module
ENTRYPOINT [ "/testrun/bin/start" ]
\ No newline at end of file
diff --git a/modules/test/base/python/requirements.txt b/modules/test/base/python/requirements.txt
index 0ed8a792d..5faa12fc8 100644
--- a/modules/test/base/python/requirements.txt
+++ b/modules/test/base/python/requirements.txt
@@ -6,4 +6,7 @@ protobuf==5.28.0
# User defined packages
grpcio==1.67.1
grpcio-tools==1.67.1
-netifaces==0.11.0
\ No newline at end of file
+netifaces==0.11.0
+
+# Requirements for reports generation
+Jinja2==3.1.5
diff --git a/modules/test/base/python/src/test_module.py b/modules/test/base/python/src/test_module.py
index 21de78143..42ee3ff85 100644
--- a/modules/test/base/python/src/test_module.py
+++ b/modules/test/base/python/src/test_module.py
@@ -42,6 +42,8 @@ def __init__(self,
self._ipv6_subnet = os.environ.get('IPV6_SUBNET', '')
self._dev_iface_mac = os.environ.get('DEV_IFACE_MAC', '')
self._device_test_pack = json.loads(os.environ.get('DEVICE_TEST_PACK', ''))
+ self._report_template_folder = os.environ.get('REPORT_TEMPLATE_PATH')
+ self._base_template_file=os.environ.get('BASE_TEMPLATE_FILE')
self._add_logger(log_name=log_name)
self._config = self._read_config(
conf_file=conf_file if conf_file is not None else CONF_FILE)
@@ -137,14 +139,14 @@ def run_tests(self):
else:
result = getattr(self, test_method_name)()
except Exception as e: # pylint: disable=W0718
- LOGGER.error(f'An error occurred whilst running {test["name"]}')
+ LOGGER.error(f'An error occurred whilst running {test["name"]}') # pylint: disable=W1405
LOGGER.error(e)
traceback.print_exc()
else:
- LOGGER.error(f'Test {test["name"]} has not been implemented')
+ LOGGER.error(f'Test {test["name"]} has not been implemented') # pylint: disable=W1405
result = TestResult.ERROR, 'This test could not be found'
else:
- LOGGER.debug(f'Test {test["name"]} is disabled')
+ LOGGER.debug(f'Test {test["name"]} is disabled') # pylint: disable=W1405
result = (TestResult.DISABLED,
'This test did not run because it is disabled')
diff --git a/modules/test/conn/python/requirements.txt b/modules/test/conn/python/requirements.txt
index 4075f79c9..d0f5db19a 100644
--- a/modules/test/conn/python/requirements.txt
+++ b/modules/test/conn/python/requirements.txt
@@ -2,7 +2,7 @@
# Package dependencies should always be defined before the user defined
# packages to prevent auto-upgrades of stable dependencies
cffi==1.17.1
-cryptography==43.0.3
+cryptography==44.0.1
pycparser==2.22
six==1.16.0
diff --git a/modules/test/dns/dns.Dockerfile b/modules/test/dns/dns.Dockerfile
index 461e87899..53f8f31f8 100644
--- a/modules/test/dns/dns.Dockerfile
+++ b/modules/test/dns/dns.Dockerfile
@@ -31,4 +31,8 @@ COPY $MODULE_DIR/conf /testrun/conf
COPY $MODULE_DIR/bin /testrun/bin
# Copy over all python files
-COPY $MODULE_DIR/python /testrun/python
\ No newline at end of file
+COPY $MODULE_DIR/python /testrun/python
+
+# Copy Jinja template
+COPY $MODULE_DIR/resources/report_template.jinja2 $REPORT_TEMPLATE_PATH/
+
diff --git a/modules/test/dns/python/src/dns_module.py b/modules/test/dns/python/src/dns_module.py
index fe244f0a7..c1db567ae 100644
--- a/modules/test/dns/python/src/dns_module.py
+++ b/modules/test/dns/python/src/dns_module.py
@@ -17,19 +17,21 @@
from test_module import TestModule
import os
from collections import Counter
+from jinja2 import Environment, FileSystemLoader
LOG_NAME = 'test_dns'
-MODULE_REPORT_FILE_NAME = 'dns_report.html'
+MODULE_REPORT_FILE_NAME = 'dns_report.j2.html'
DNS_SERVER_CAPTURE_FILE = '/runtime/network/dns.pcap'
STARTUP_CAPTURE_FILE = '/runtime/device/startup.pcap'
MONITOR_CAPTURE_FILE = '/runtime/device/monitor.pcap'
LOGGER = None
+REPORT_TEMPLATE_FILE = 'report_template.jinja2'
class DNSModule(TestModule):
"""DNS Test module"""
- def __init__(self,
+ def __init__(self, # pylint: disable=R0917
module,
conf_file=None,
results_dir=None,
@@ -48,11 +50,37 @@ def __init__(self,
LOGGER = self._get_logger()
def generate_module_report(self):
+ # Load Jinja2 template
+ page_max_height = 850
+ header_height = 48
+ summary_height = 135
+ row_height = 44
+ loader=FileSystemLoader(self._report_template_folder)
+ template = Environment(
+ loader=loader,
+ trim_blocks=True,
+ lstrip_blocks=True
+ ).get_template(REPORT_TEMPLATE_FILE)
+ module_header='DNS Module'
+ # Summary table headers
+ summary_headers = [
+ 'Requests to local DNS server',
+ 'Requests to external DNS servers',
+ 'Total DNS requests',
+ 'Total DNS responses',
+ ]
+ # Module data Headers
+ module_data_headers = [
+ 'Source',
+ 'Destination',
+ 'Resolved IP',
+ 'Type',
+ 'URL',
+ 'Count',
+ ]
# Extract DNS data from the pcap file
dns_table_data = self.extract_dns_data()
- html_content = 'DNS Module '
-
# Set the summary variables
local_requests = sum(
1 for row in dns_table_data
@@ -67,79 +95,59 @@ def generate_module_report(self):
if row['Type'] == 'Response')
# Add summary table
- html_content += (f'''
-
-
-
- Requests to local DNS server
- Requests to external DNS servers
- Total DNS requests
- Total DNS responses
-
-
-
-
- {local_requests}
- {external_requests}
- {total_requests}
- {total_responses}
-
-
- ''')
-
+ summary_data = [
+ local_requests,
+ external_requests,
+ total_requests,
+ total_responses,
+ ]
+
+ module_data = []
if (total_requests + total_responses) > 0:
- table_content = '''
-
-
-
- Source
- Destination
- Resolved IP
- Type
- URL
- Count
-
-
- '''
-
# Count unique combinations
counter = Counter((row['Source'], row['Destination'], row['ResolvedIP'],
row['Type'], row['Data']) for row in dns_table_data)
# Generate the HTML table with the count column
for (src, dst, res_ip, typ, dat), count in counter.items():
- table_content += f'''
-
- {src}
- {dst}
- {res_ip}
- {typ}
- {dat}
- {count}
- '''
-
- table_content += '''
-
-
'''
-
- html_content += table_content
-
- else:
- html_content += ('''
-
-
- No DNS traffic detected from the device
-
''')
-
- LOGGER.debug('Module report:\n' + html_content)
+ module_data.append({
+ 'src': src,
+ 'dst': dst,
+ 'res_ip': res_ip,
+ 'typ': typ,
+ 'dat': dat,
+ 'count': count,
+ })
+ # Handling the possible table split
+ table_height = (len(module_data) + 1) * row_height
+ page_useful_space = page_max_height - header_height - summary_height
+ pages = table_height // (page_useful_space)
+ rows_on_page = (page_useful_space) // row_height
+ start = 0
+ report_html = ''
+ for page in range(pages+1):
+ end = start + min(len(module_data), rows_on_page)
+ module_header_repr = module_header if page == 0 else None
+ page_html = template.render(
+ base_template=self._base_template_file,
+ module_header=module_header_repr,
+ summary_headers=summary_headers,
+ summary_data=summary_data,
+ module_data_headers=module_data_headers,
+ module_data=module_data[start:end]
+ )
+ report_html += page_html
+ start = end
+
+ LOGGER.debug('Module report:\n' + report_html)
# Use os.path.join to create the complete file path
report_path = os.path.join(self._results_dir, MODULE_REPORT_FILE_NAME)
# Write the content to a file
with open(report_path, 'w', encoding='utf-8') as file:
- file.write(html_content)
+ file.write(report_html)
LOGGER.info('Module report generated at: ' + str(report_path))
diff --git a/modules/test/dns/resources/report_template.jinja2 b/modules/test/dns/resources/report_template.jinja2
new file mode 100644
index 000000000..8e701a8e3
--- /dev/null
+++ b/modules/test/dns/resources/report_template.jinja2
@@ -0,0 +1,31 @@
+{% extends base_template %}
+{% block content %}
+{% if module_data %}
+
+
+
+ {% for header in module_data_headers %}
+ {{ header }}
+ {% endfor %}
+
+
+
+ {% for row in module_data %}
+
+ {{ row['src'] }}
+ {{ row['dst'] }}
+ {{ row['res_ip'] }}
+ {{ row['typ'] }}
+ {{ row['dat'] }}
+ {{ row['count'] }}
+
+ {% endfor %}
+
+
+{% else %}
+
+
+ No DNS traffic detected from the device
+
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/modules/test/ntp/ntp.Dockerfile b/modules/test/ntp/ntp.Dockerfile
index 4d9701464..c7ae7fee1 100644
--- a/modules/test/ntp/ntp.Dockerfile
+++ b/modules/test/ntp/ntp.Dockerfile
@@ -31,4 +31,7 @@ COPY $MODULE_DIR/conf /testrun/conf
COPY $MODULE_DIR/bin /testrun/bin
# Copy over all python files
-COPY $MODULE_DIR/python /testrun/python
\ No newline at end of file
+COPY $MODULE_DIR/python /testrun/python
+
+# Copy Jinja template
+COPY $MODULE_DIR/resources/report_template.jinja2 $REPORT_TEMPLATE_PATH/
\ No newline at end of file
diff --git a/modules/test/ntp/python/src/ntp_module.py b/modules/test/ntp/python/src/ntp_module.py
index 33729a8d1..8bc609502 100644
--- a/modules/test/ntp/python/src/ntp_module.py
+++ b/modules/test/ntp/python/src/ntp_module.py
@@ -17,19 +17,21 @@
from scapy.error import Scapy_Exception
import os
from collections import defaultdict
+from jinja2 import Environment, FileSystemLoader
LOG_NAME = 'test_ntp'
-MODULE_REPORT_FILE_NAME = 'ntp_report.html'
+MODULE_REPORT_FILE_NAME = 'ntp_report.j2.html'
NTP_SERVER_CAPTURE_FILE = '/runtime/network/ntp.pcap'
STARTUP_CAPTURE_FILE = '/runtime/device/startup.pcap'
MONITOR_CAPTURE_FILE = '/runtime/device/monitor.pcap'
LOGGER = None
+REPORT_TEMPLATE_FILE = 'report_template.jinja2'
class NTPModule(TestModule):
"""NTP Test module"""
- def __init__(self,
+ def __init__(self, # pylint: disable=R0917
module,
conf_file=None,
results_dir=None,
@@ -50,11 +52,38 @@ def __init__(self,
LOGGER = self._get_logger()
def generate_module_report(self):
+ # Load Jinja2 template
+ page_max_height = 910
+ header_height = 48
+ summary_height = 135
+ row_height = 42
+ loader=FileSystemLoader(self._report_template_folder)
+ template = Environment(
+ loader=loader,
+ trim_blocks=True,
+ lstrip_blocks=True,
+ ).get_template(REPORT_TEMPLATE_FILE)
+ module_header='NTP Module'
+ # Summary table headers
+ summary_headers = [
+ 'Requests to local NTP server',
+ 'Requests to external NTP servers',
+ 'Total NTP requests',
+ 'Total NTP responses'
+ ]
+ # Module data Headers
+ module_data_headers = [
+ 'Source',
+ 'Destination',
+ 'Type',
+ 'Version',
+ 'Count',
+ 'Sync Request Average',
+ ]
+
# Extract NTP data from the pcap file
ntp_table_data = self.extract_ntp_data()
- html_content = 'NTP Module '
-
# Set the summary variables
local_requests = sum(
1 for row in ntp_table_data
@@ -68,6 +97,14 @@ def generate_module_report(self):
total_responses = sum(1 for row in ntp_table_data
if row['Type'] == 'Server')
+ # Summary table data
+ summary_data = [
+ local_requests,
+ external_requests,
+ total_requests,
+ total_responses
+ ]
+
# Initialize a dictionary to store timestamps for each unique combination
timestamps = defaultdict(list)
@@ -95,42 +132,9 @@ def generate_module_report(self):
average_time_between_requests[key] = avg_diff
- # Add summary table
- html_content += (f'''
-
-
-
- Requests to local NTP server
- Requests to external NTP servers
- Total NTP requests
- Total NTP responses
-
-
-
-
- {local_requests}
- {external_requests}
- {total_requests}
- {total_responses}
-
-
-
- ''')
-
+ # Module table data
+ module_table_data = []
if total_requests + total_responses > 0:
- table_content = '''
-
-
-
- Source
- Destination
- Type
- Version
- Count
- Sync Request Average
-
-
- '''
# Generate the HTML table with the count column
for (src, dst, typ,
@@ -145,37 +149,44 @@ def generate_module_report(self):
else:
avg_formatted_time = 'N/A'
- table_content += f'''
-
- {src}
- {dst}
- {typ}
- {version}
- {cnt}
- {avg_formatted_time}
- '''
-
- table_content += '''
-
-
- '''
- html_content += table_content
-
- else:
- html_content += ('''
-
-
- No NTP traffic detected from the device
-
''')
-
- LOGGER.debug('Module report:\n' + html_content)
+ module_table_data.append({
+ 'src': src,
+ 'dst': dst,
+ 'typ': typ,
+ 'version': version,
+ 'cnt': cnt,
+ 'avg_fmt': avg_formatted_time
+ })
+
+ # Handling the possible table split
+ table_height = (len(module_table_data) + 1) * row_height
+ page_useful_space = page_max_height - header_height - summary_height
+ pages = table_height // (page_useful_space)
+ rows_on_page = ((page_useful_space) // row_height) - 1
+ start = 0
+ report_html = ''
+ for page in range(pages+1):
+ end = start + min(len(module_table_data), rows_on_page)
+ module_header_repr = module_header if page == 0 else None
+ page_html = template.render(
+ base_template=self._base_template_file,
+ module_header=module_header_repr,
+ summary_headers=summary_headers,
+ summary_data=summary_data,
+ module_data_headers=module_data_headers,
+ module_data=module_table_data[start:end]
+ )
+ report_html += page_html
+ start = end
+
+ LOGGER.debug('Module report:\n' + report_html)
# Use os.path.join to create the complete file path
report_path = os.path.join(self._results_dir, MODULE_REPORT_FILE_NAME)
# Write the content to a file
with open(report_path, 'w', encoding='utf-8') as file:
- file.write(html_content)
+ file.write(report_html)
LOGGER.info('Module report generated at: ' + str(report_path))
@@ -276,7 +287,7 @@ def _ntp_network_ntp_support(self):
result = False, 'Device has not sent any NTP requests'
if device_sends_ntp3 and device_sends_ntp4:
- result = False, ('Device sent NTPv3 and NTPv4 packets')
+ result = True, ('Device sent NTPv3 and NTPv4 packets')
elif device_sends_ntp3:
result = False, ('Device sent NTPv3 packets')
elif device_sends_ntp4:
diff --git a/modules/test/ntp/resources/report_template.jinja2 b/modules/test/ntp/resources/report_template.jinja2
new file mode 100644
index 000000000..c3601b67b
--- /dev/null
+++ b/modules/test/ntp/resources/report_template.jinja2
@@ -0,0 +1,31 @@
+{% extends base_template %}
+{% block content %}
+{% if module_data %}
+
+
+
+ {% for header in module_data_headers %}
+ {{ header }}
+ {% endfor %}
+
+
+
+ {% for row in module_data %}
+
+ {{ row['src'] }}
+ {{ row['dst'] }}
+ {{ row['typ'] }}
+ {{ row['version'] }}
+ {{ row['cnt'] }}
+ {{ row['avg_fmt'] }}
+
+ {% endfor %}
+
+
+{% else %}
+
+
+ No NTP traffic detected from the device
+
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/modules/test/services/python/src/services_module.py b/modules/test/services/python/src/services_module.py
index 1a783e7dc..3ec713962 100644
--- a/modules/test/services/python/src/services_module.py
+++ b/modules/test/services/python/src/services_module.py
@@ -19,17 +19,19 @@
import xmltodict
from test_module import TestModule
import os
+from jinja2 import Environment, FileSystemLoader
LOG_NAME = 'test_services'
-MODULE_REPORT_FILE_NAME = 'services_report.html'
+MODULE_REPORT_FILE_NAME = 'services_report.j2.html'
NMAP_SCAN_RESULTS_SCAN_FILE = 'services_scan_results.json'
LOGGER = None
+REPORT_TEMPLATE_FILE = 'report_template.jinja2'
class ServicesModule(TestModule):
"""Services Test module"""
- def __init__(self,
+ def __init__(self, # pylint: disable=R0917
module,
conf_file=None,
results_dir=None,
@@ -52,6 +54,26 @@ def __init__(self,
self._run_nmap()
def generate_module_report(self):
+ # Load Jinja2 template
+ loader=FileSystemLoader(self._report_template_folder)
+ template = Environment(
+ loader=loader,
+ trim_blocks=True,
+ lstrip_blocks=True
+ ).get_template(REPORT_TEMPLATE_FILE)
+ module_header = 'Services Module'
+ summary_headers = [
+ 'TCP ports open',
+ 'UDP ports open',
+ 'Total ports open',
+ ]
+ module_data_headers = [
+ 'Port',
+ 'State',
+ 'Service',
+ 'Version',
+ ]
+
# Use os.path.join to create the complete file path
nmap_scan_results_file = os.path.join(self._nmap_scan_results_path,
NMAP_SCAN_RESULTS_SCAN_FILE)
@@ -81,65 +103,32 @@ def generate_module_report(self):
else:
udp_open += 1
- html_content = 'Services Module '
-
- # Add summary table
- html_content += (f'''
-
-
-
- TCP ports open
- UDP ports open
- Total ports open
-
-
-
-
- {tcp_open}
- {udp_open}
- {tcp_open + udp_open}
-
-
- ''')
+ summary_data = [
+ tcp_open,
+ udp_open,
+ tcp_open + udp_open,
+ ]
+ module_data = []
if (tcp_open + udp_open) > 0:
-
- table_content = '''
-
-
-
- Port
- State
- Service
- Version
-
-
- '''
-
for row in nmap_table_data:
-
- table_content += (f'''
-
- {row['Port']}/{row['Type']}
- {row['State']}
- {row['Service']}
- {row['Version']}
- ''')
-
- table_content += '''
-
-
- '''
-
- html_content += table_content
-
- else:
-
- html_content += ('''
-
-
- No open ports detected
-
''')
+ port = row['Port']
+ type_ = row['Type']
+ module_data.append({
+ 'Port': f'{port}/{type_}',
+ 'State': row['State'],
+ 'Service': row['Service'],
+ 'Version': row['Version'],
+ })
+
+ html_content = template.render(
+ base_template=self._base_template_file,
+ module_header=module_header,
+ summary_headers=summary_headers,
+ summary_data=summary_data,
+ module_data_headers=module_data_headers,
+ module_data=module_data,
+ )
LOGGER.debug('Module report:\n' + html_content)
@@ -156,6 +145,8 @@ def generate_module_report(self):
def _run_nmap(self):
LOGGER.info('Running nmap')
+ self._device_ipv4_addr = self._get_device_ipv4()
+ LOGGER.info('Resolved device IP: ' + str(self._device_ipv4_addr))
# Run the monitor method asynchronously to keep this method non-blocking
self._tcp_scan_thread = threading.Thread(target=self._scan_tcp_ports)
@@ -202,7 +193,9 @@ def _scan_tcp_ports(self):
--version-intensity 7 -T4 -oX - {self._ipv4_addr}''')[0]
LOGGER.info('TCP port scan complete')
+ LOGGER.debug(f'TCP Scan results raw: {nmap_results}')
nmap_results_json = self._nmap_results_to_json(nmap_results)
+ LOGGER.debug(f'TCP Scan results JSON: {nmap_results_json}')
self._scan_tcp_results = self._process_nmap_json_results(
nmap_results_json=nmap_results_json)
@@ -228,7 +221,9 @@ def _scan_udp_ports(self):
nmap_results = util.run_command( # pylint: disable=E1120
f'nmap -sU -sV -p {port_list} -oX - {self._ipv4_addr}')[0]
LOGGER.info('UDP port scan complete')
+ LOGGER.debug(f'UDP Scan results raw: {nmap_results}')
nmap_results_json = self._nmap_results_to_json(nmap_results)
+ LOGGER.debug(f'UDP Scan results JSON: {nmap_results_json}')
self._scan_udp_results = self._process_nmap_json_results(
nmap_results_json=nmap_results_json)
diff --git a/modules/test/services/resources/report_template.jinja2 b/modules/test/services/resources/report_template.jinja2
new file mode 100644
index 000000000..c9b1438ae
--- /dev/null
+++ b/modules/test/services/resources/report_template.jinja2
@@ -0,0 +1,29 @@
+{% extends base_template %}
+{% block content %}
+{% if module_data %}
+
+
+
+ {% for header in module_data_headers %}
+ {{ header }}
+ {% endfor %}
+
+
+
+ {% for row in module_data %}
+
+ {{ row['Port'] }}
+ {{ row['State'] }}
+ {{ row['Service'] }}
+ {{ row['Version'] }}
+
+ {% endfor %}
+
+
+{% else %}
+
+
+ No open ports detected
+
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/modules/test/services/services.Dockerfile b/modules/test/services/services.Dockerfile
index 8dcaafcc1..1277c2f8d 100644
--- a/modules/test/services/services.Dockerfile
+++ b/modules/test/services/services.Dockerfile
@@ -31,4 +31,7 @@ COPY $MODULE_DIR/conf /testrun/conf
COPY $MODULE_DIR/bin /testrun/bin
# Copy over all python files
-COPY $MODULE_DIR/python /testrun/python
\ No newline at end of file
+COPY $MODULE_DIR/python /testrun/python
+
+# Copy Jinja template
+COPY $MODULE_DIR/resources/report_template.jinja2 $REPORT_TEMPLATE_PATH/
\ No newline at end of file
diff --git a/modules/test/tls/conf/module_config.json b/modules/test/tls/conf/module_config.json
index 9c83c85df..228fbb64d 100644
--- a/modules/test/tls/conf/module_config.json
+++ b/modules/test/tls/conf/module_config.json
@@ -9,7 +9,7 @@
"docker": {
"depends_on": "base",
"enable_container": true,
- "timeout": 420
+ "timeout": 540
},
"tests":[
{
diff --git a/modules/test/tls/python/requirements.txt b/modules/test/tls/python/requirements.txt
index 4f241ef86..2cbc1db46 100644
--- a/modules/test/tls/python/requirements.txt
+++ b/modules/test/tls/python/requirements.txt
@@ -13,9 +13,9 @@ termcolor==2.4.0
urllib3==2.2.2
# User defined packages
-cryptography==43.0.0
+cryptography==44.0.1
pyOpenSSL==24.3.0
lxml==5.1.0 # Requirement of pyshark but if upgraded automatically above 5.1 will cause a
pyshark==0.6
requests==2.32.3
-
+python-nmap==0.7.1
diff --git a/modules/test/tls/python/src/http_scan.py b/modules/test/tls/python/src/http_scan.py
new file mode 100644
index 000000000..a25f5215d
--- /dev/null
+++ b/modules/test/tls/python/src/http_scan.py
@@ -0,0 +1,76 @@
+# Copyright 2023 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Module that contains various methods for scaning for HTTP/HTTPS services"""
+import nmap
+import socket
+import ssl
+
+LOGGER = None
+
+
+class HTTPScan():
+ """Helper class to scan for all HTTP/HTTPS services for a device"""
+
+ def __init__(self, logger):
+ global LOGGER
+ LOGGER = logger
+
+ def scan_all_ports(self, ip):
+ """Scans all ports and identifies potential HTTP/HTTPS ports."""
+ nm = nmap.PortScanner()
+ nm.scan(hosts=ip, ports='1-65535', arguments='--open -sV')
+
+ http_ports = []
+ for host in nm.all_hosts():
+ for proto in nm[host].all_protocols():
+ for port in nm[host][proto].keys():
+ service = nm[host][proto][port]['name']
+ if 'http' in service:
+ http_ports.append(port)
+ return http_ports
+
+ def is_https(self, ip, port):
+ """Attempts a TLS handshake to determine if the port serves HTTPS."""
+ try:
+ context = ssl.create_default_context()
+ context.check_hostname = False
+ context.verify_mode = ssl.CERT_NONE
+ with socket.create_connection((ip, port), timeout=2) as sock:
+ with context.wrap_socket(sock, server_hostname=ip):
+ return True
+ except ssl.SSLError:
+ return False
+ except Exception: # pylint: disable=W0718
+ return False
+
+ def verify_http_or_https(self, ip, ports):
+ """Classifies each port as HTTP or HTTPS."""
+ results = {}
+ for port in ports:
+ if self.is_https(ip, port):
+ results[port] = 'HTTPS'
+ else:
+ results[port] = 'HTTP'
+ return results
+
+ def scan_for_http_services(self, ip_address):
+ LOGGER.info(f'Scanning for HTTP ports on {ip_address}')
+ http_ports = self.scan_all_ports(ip_address)
+ results = None
+ if len(http_ports) > 0:
+ LOGGER.info(f'Checking HTTP ports on {ip_address}: {http_ports}')
+ results = self.verify_http_or_https(ip_address, http_ports)
+ for port, service_type in results.items():
+ LOGGER.info(f'Port {port}: {service_type}')
+ return results
diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py
index e9163843a..3ccd96b59 100644
--- a/modules/test/tls/python/src/tls_module.py
+++ b/modules/test/tls/python/src/tls_module.py
@@ -16,6 +16,7 @@
from test_module import TestModule
from tls_util import TLSUtil
+from http_scan import HTTPScan
import os
import pyshark
from binascii import hexlify
@@ -25,20 +26,22 @@
from cryptography.hazmat.primitives.asymmetric import rsa, dsa, ec
from cryptography.x509 import AuthorityKeyIdentifier, SubjectKeyIdentifier, BasicConstraints, KeyUsage
from cryptography.x509 import GeneralNames, DNSName, ExtendedKeyUsage, ObjectIdentifier, SubjectAlternativeName
+from jinja2 import Environment, FileSystemLoader
LOG_NAME = 'test_tls'
-MODULE_REPORT_FILE_NAME = 'tls_report.html'
+MODULE_REPORT_FILE_NAME = 'tls_report.j2.html'
STARTUP_CAPTURE_FILE = '/runtime/device/startup.pcap'
MONITOR_CAPTURE_FILE = '/runtime/device/monitor.pcap'
TLS_CAPTURE_FILE = '/runtime/output/tls.pcap'
GATEWAY_CAPTURE_FILE = '/runtime/network/gateway.pcap'
LOGGER = None
+REPORT_TEMPLATE_FILE = 'report_template.jinja2'
class TLSModule(TestModule):
"""The TLS testing module."""
- def __init__(self,
+ def __init__(self, # pylint: disable=R0917
module,
conf_file=None,
results_dir=None,
@@ -55,9 +58,32 @@ def __init__(self,
global LOGGER
LOGGER = self._get_logger()
self._tls_util = TLSUtil(LOGGER)
+ self._http_scan = HTTPScan(LOGGER)
+ self._scan_results = None
def generate_module_report(self):
- html_content = 'TLS Module '
+ # Load Jinja2 template
+ loader=FileSystemLoader(self._report_template_folder)
+ template = Environment(
+ loader=loader,
+ trim_blocks=True,
+ lstrip_blocks=True
+ ).get_template(REPORT_TEMPLATE_FILE)
+ module_header='TLS Module'
+ # Summary table headers
+ summary_headers = [
+ 'Expiry',
+ 'Length',
+ 'Type',
+ 'Port number',
+ 'Signed by',
+ ]
+ # Cert table headers
+ cert_table_headers = ['Property', 'Value']
+ # Outbound connections table headers
+ outbound_headers = ['Destination IP', 'Port']
+ pages = {}
+ outbound_conns = None
# List of capture files to scan
pcap_files = [
@@ -66,39 +92,12 @@ def generate_module_report(self):
]
certificates = self.extract_certificates_from_pcap(pcap_files,
self._device_mac)
-
if len(certificates) > 0:
- cert_tables = []
# pylint: disable=W0612
for cert_num, ((ip_address, port),
cert) in enumerate(certificates.items()):
-
- # Add summary table
- summary_table = '''
-
-
-
- Expiry
- Length
- Type
- Port number
- Signed by
-
-
-
- '''
-
- # Generate the certificate table
- cert_table = '''
-
-
-
- Property
- Value
-
-
- '''
+ pages[cert_num] = {}
# Extract certificate data
not_valid_before = cert.not_valid_before
@@ -124,50 +123,18 @@ def generate_module_report(self):
cert.public_bytes(encoding=serialization.Encoding.DER))
# Append certification information
- cert_table += f'''
-
- Version
- {version_value}
-
-
- Signature Alg.
- {signature_alg_value}
-
-
- Validity from
- {not_before}
-
-
- Valid to
- {not_after}
-
-
-
- '''
-
- subject_table = '''
-
-
-
- Property
- Value
-
-
- '''
+ pages[cert_num]['cert_info_data'] = {
+ 'Version': version_value,
+ 'Signature Alg.': signature_alg_value,
+ 'Validity from': not_before,
+ 'Valid to': not_after,
+ }
# Append the subject information
+ pages[cert_num]['subject_data'] = {}
for val in cert.subject.rdns:
dn = val.rfc4514_string().split('=')
- subject_table += f'''
-
- {dn[0]}
- {dn[1]}
-
- '''
-
- subject_table += '''
-
-
'''
+ pages[cert_num]['subject_data'][dn[0]] = dn[1]
# Append issuer information
for val in cert.issuer.rdns:
@@ -175,101 +142,72 @@ def generate_module_report(self):
if 'CN' in dn[0]:
signed_by = dn[1]
- ext_table = ''
-
# Append extensions information
if cert.extensions:
-
- ext_table = '''
- Certificate Extensions
-
-
-
- Property
- Value
-
-
- '''
-
+ pages[cert_num]['cert_ext'] = {}
for extension in cert.extensions:
if isinstance(extension.value, list):
for extension_value in extension.value:
- ext_table += f'''
-
- {extension.oid._name}
- {self.format_extension_value(extension_value.value)}
-
- '''
+ extension_name = extension.oid._name
+ formatted_value = self.format_extension_value(
+ extension_value.value)
+ pages[cert_num]['cert_ext'][extension_name] = formatted_value
else:
- ext_table += f'''
-
- {extension.oid._name}
- {self.format_extension_value(extension.value)}
-
- '''
-
- ext_table += '''
-
-
'''
-
- # Add summary table row
- summary_table += f'''
-
- {not_after}
- {cert_length}
- {public_key_type}
- {port}
- {signed_by}
-
-
-
- '''
-
- # Merge all table HTML
- summary_table = f'\n{summary_table}'
-
- summary_table += f'''
-
-
-
Certificate Information
- {cert_table}
-
-
-
Subject Information
- {subject_table}
-
-
'''
-
- if ext_table is not None:
- summary_table += f'\n\n{ext_table}'
-
- cert_tables.append(summary_table)
+ formatted_value = self.format_extension_value(
+ extension.value)
+ pages[cert_num]['cert_ext'][extension.oid._name] = formatted_value
+
+ pages[cert_num]['summary_data'] = [
+ not_after,
+ cert_length,
+ public_key_type,
+ port,
+ signed_by
+ ]
outbound_conns = self._tls_util.get_all_outbound_connections(
device_mac=self._device_mac, capture_files=pcap_files)
- conn_table = self.generate_outbound_connection_table(outbound_conns)
-
- html_content += '\n'.join('\n' + tables for tables in cert_tables)
- html_content += conn_table
+ report_jinja = ''
+ if pages:
+ for num,page in pages.items():
+ module_header_repr = module_header if num == 0 else None
+ cert_ext=page['cert_ext'] if 'cert_ext' in page else None
+ page_html = template.render(
+ base_template=self._base_template_file,
+ module_header=module_header_repr,
+ summary_headers=summary_headers,
+ summary_data=page['summary_data'],
+ cert_info_data=page['cert_info_data'],
+ subject_data=page['subject_data'],
+ cert_table_headers=cert_table_headers,
+ cert_ext=cert_ext,
+ ountbound_headers=outbound_headers,
+ )
+ report_jinja += page_html
+ if outbound_conns:
+ out_page = template.render(
+ base_template=self._base_template_file,
+ ountbound_headers=outbound_headers,
+ outbound_conns=outbound_conns
+ )
+ report_jinja += out_page
else:
- html_content += ('''
-
-
- No TLS certificates found on the device
-
''')
-
- LOGGER.debug('Module report:\n' + html_content)
+ report_jinja = template.render(
+ base_template=self._base_template_file,
+ module_header = module_header,
+ )
+ LOGGER.debug('Module report:\n' + report_jinja)
# Use os.path.join to create the complete file path
- report_path = os.path.join(self._results_dir, MODULE_REPORT_FILE_NAME)
+ jinja_path = os.path.join(self._results_dir, MODULE_REPORT_FILE_NAME)
# Write the content to a file
- with open(report_path, 'w', encoding='utf-8') as file:
- file.write(html_content)
+ with open(jinja_path, 'w', encoding='utf-8') as file:
+ file.write(report_jinja)
- LOGGER.info('Module report generated at: ' + str(report_path))
- return report_path
+ LOGGER.info('Module report generated at: ' + str(jinja_path))
+ return jinja_path
def format_extension_value(self, value):
if isinstance(value, bytes):
@@ -353,8 +291,8 @@ def extract_certificates_from_pcap(self, pcap_files, mac_address):
all_packets = []
# Iterate over each file
for pcap_file in pcap_files:
- # Open the capture file
- packets = pyshark.FileCapture(pcap_file)
+ # Open the capture file and filter by tls
+ packets = pyshark.FileCapture(pcap_file, display_filter='tls')
try:
# Iterate over each packet in the file and add it to the list
for packet in packets:
@@ -387,53 +325,102 @@ def extract_certificates_from_pcap(self, pcap_files, mac_address):
def _security_tls_v1_2_server(self):
LOGGER.info('Running security.tls.v1_2_server')
- self._resolve_device_ip()
# If the ipv4 address wasn't resolved yet, try again
+ self._resolve_device_ip()
+ ports_valid = []
+ ports_invalid = []
+ result = None
+ details = ''
+ description = ''
if self._device_ipv4_addr is not None:
- tls_1_2_results = self._tls_util.validate_tls_server(
- self._device_ipv4_addr, tls_version='1.2')
- tls_1_3_results = self._tls_util.validate_tls_server(
- self._device_ipv4_addr, tls_version='1.3')
- results = self._tls_util.process_tls_server_results(
- tls_1_2_results, tls_1_3_results)
+ if self._scan_results is None:
+ self._scan_results = self._http_scan.scan_for_http_services(
+ self._device_ipv4_addr)
+ if self._scan_results is not None:
+ for port, service_type in self._scan_results.items():
+ if 'HTTPS' in service_type:
+ LOGGER.info(f'Inspecting Service on port {port}: {service_type}')
+ tls_1_2_results = self._tls_util.validate_tls_server(
+ host=self._device_ipv4_addr, port=port, tls_version='1.2')
+ tls_1_3_results = self._tls_util.validate_tls_server(
+ host=self._device_ipv4_addr, port=port, tls_version='1.3')
+ port_results = self._tls_util.process_tls_server_results(
+ tls_1_2_results, tls_1_3_results, port=port)
+ if port_results is not None:
+ result = port_results[
+ 0] if result is None else result and port_results[0]
+ details += port_results[1]
+ if port_results[0]:
+ ports_valid.append(port)
+ else:
+ ports_invalid.append(port)
+ elif 'HTTP' in service_type:
+ # Any non-HTTPS service detetcted is automatically invalid
+ ports_invalid.append(port)
+ details += f'\nHTTP service detected on port {port}'
+ result = False
+ LOGGER.debug(f'Valid Ports: {ports_valid}')
+ LOGGER.debug(f'Invalid Ports: {ports_invalid}')
# Determine results and return proper messaging and details
- description = ''
- result = results[0]
- details = results[1]
if result is None:
result = 'Feature Not Detected'
description = 'TLS 1.2 certificate could not be validated'
elif result:
- description = 'TLS 1.2 certificate is valid'
+ ports_csv = ','.join(map(str,ports_valid))
+ description = f'TLS 1.2 certificate valid on ports: {ports_csv}'
else:
- description = 'TLS 1.2 certificate is invalid'
+ ports_csv = ','.join(map(str,ports_invalid))
+ description = f'TLS 1.2 certificate invalid on ports: {ports_csv}'
return result, description, details
-
else:
LOGGER.error('Could not resolve device IP address. Skipping')
return 'Error', 'Could not resolve device IP address'
def _security_tls_v1_3_server(self):
LOGGER.info('Running security.tls.v1_3_server')
- self._resolve_device_ip()
# If the ipv4 address wasn't resolved yet, try again
+ self._resolve_device_ip()
+ ports_valid = []
+ ports_invalid = []
+ result = None
+ details = ''
+ description = ''
if self._device_ipv4_addr is not None:
- results = self._tls_util.validate_tls_server(self._device_ipv4_addr,
- tls_version='1.3')
+ if self._scan_results is None:
+ self._scan_results = self._http_scan.scan_for_http_services(
+ self._device_ipv4_addr)
+ if self._scan_results is not None:
+ for port, service_type in self._scan_results.items():
+ if 'HTTPS' in service_type:
+ LOGGER.info(f'Inspecting Service on port {port}: {service_type}')
+ port_results = self._tls_util.validate_tls_server(
+ self._device_ipv4_addr, tls_version='1.3', port=port)
+ if port_results is not None:
+ result = port_results[
+ 0] if result is None else result and port_results[0]
+ details += port_results[1]
+ if port_results[0]:
+ ports_valid.append(port)
+ else:
+ ports_invalid.append(port)
+ elif 'HTTP' in service_type:
+ # Any non-HTTPS service detetcted is automatically invalid
+ ports_invalid.append(port)
+ details += f'\nHTTP service detected on port {port}'
+ result = False
+ LOGGER.debug(f'Valid Ports: {ports_valid}')
+ LOGGER.debug(f'Invalid Ports: {ports_invalid}')
# Determine results and return proper messaging and details
- description = ''
- result = results[0]
- details = results[1]
- description = ''
if result is None:
result = 'Feature Not Detected'
description = 'TLS 1.3 certificate could not be validated'
- elif results[0]:
- description = 'TLS 1.3 certificate is valid'
+ elif result:
+ ports_csv = ','.join(map(str,ports_valid))
+ description = f'TLS 1.3 certificate valid on ports: {ports_csv}'
else:
- description = 'TLS 1.3 certificate is invalid'
+ ports_csv = ','.join(map(str,ports_invalid))
+ description = f'TLS 1.3 certificate invalid on ports: {ports_csv}'
return result, description, details
-
else:
LOGGER.error('Could not resolve device IP address')
return 'Error', 'Could not resolve device IP address'
@@ -472,14 +459,14 @@ def _security_tls_v1_0_client(self):
def _security_tls_v1_2_client(self):
LOGGER.info('Running security.tls.v1_2_client')
return self._validate_tls_client(self._device_mac,
- '1.2',
- unsupported_versions=['1.0', '1.1'])
+ '1.2',
+ unsupported_versions=['1.0', '1.1'])
def _security_tls_v1_3_client(self):
LOGGER.info('Running security.tls.v1_3_client')
return self._validate_tls_client(self._device_mac,
- '1.3',
- unsupported_versions=['1.0', '1.1'])
+ '1.3',
+ unsupported_versions=['1.0', '1.1'])
def _validate_tls_client(self,
client_mac,
@@ -509,10 +496,10 @@ def _validate_tls_client(self,
result_message = f'TLS {tls_version} client connections invalid'
else:
result_state = 'Feature Not Detected'
- result_message = 'No outbound connections were found'
+ result_message = 'No outbound TLS connections were found'
return result_state, result_message, result_details, result_tags
def _resolve_device_ip(self):
# If the ipv4 address wasn't resolved yet, try again
- if self._device_ipv4_addr is None:
+ if self._device_ipv4_addr is None: # pylint: disable=E0203
self._device_ipv4_addr = self._get_device_ipv4()
diff --git a/modules/test/tls/python/src/tls_util.py b/modules/test/tls/python/src/tls_util.py
index 37cd89133..d92379aab 100644
--- a/modules/test/tls/python/src/tls_util.py
+++ b/modules/test/tls/python/src/tls_util.py
@@ -221,11 +221,11 @@ def verify_public_key(self, public_key):
else:
return False, 'Key is not RSA or EC type'
- def validate_signature(self, host):
+ def validate_signature(self, host, port):
# Reconnect to the device but with validate signature option
# set to true which will check for proper cert chains
# within the valid CA root certs stored on the server
- if self.validate_trusted_ca_signature(host):
+ if self.validate_trusted_ca_signature(host, port):
LOGGER.info('Authorized Certificate Authority signature confirmed')
return True, 'Authorized Certificate Authority signature confirmed'
else:
@@ -261,13 +261,14 @@ def validate_local_ca_signature(self, device_cert_path):
LOGGER.error(str(e))
return False, None
- def validate_trusted_ca_signature(self, host):
+ def validate_trusted_ca_signature(self, host, port):
# Reconnect to the device but with validate signature option
# set to true which will check for proper cert chains
# within the valid CA root certs stored on the server
LOGGER.info(
'Checking for valid signature from authorized Certificate Authorities')
- public_cert = self.get_public_certificate(host,
+ public_cert = self.get_public_certificate(host=host,
+ port=port,
validate_cert=True,
tls_version='1.2')
if public_cert:
@@ -377,34 +378,41 @@ def get_certificate(self, uri, timeout=10):
LOGGER.error(f'Error fetching certificate from URI: {e}')
return certificate
- def process_tls_server_results(self, tls_1_2_results, tls_1_3_results):
+ def process_tls_server_results(self, tls_1_2_results, tls_1_3_results, port):
results = ''
if tls_1_2_results[0] is None and tls_1_3_results[0] is not None:
# Validate only TLS 1.3 results
- description = 'TLS 1.3' + (' not' if not tls_1_3_results[0] else
- '') + ' validated: ' + tls_1_3_results[1]
+ description = (f"""TLS 1.3 {'' if tls_1_3_results[0] else 'not '}"""
+ f"""validated on port {port}: """
+ f"""{tls_1_3_results[1]}""")
results = tls_1_3_results[0], description
elif tls_1_3_results[0] is None and tls_1_2_results[0] is not None:
# Vaidate only TLS 1.2 results
- description = 'TLS 1.2' + (' not' if not tls_1_2_results[0] else
- '') + ' validated: ' + tls_1_2_results[1]
+ description = (f"""TLS 1.2 {'' if tls_1_2_results[0] else 'not '}"""
+ f"""validated on port {port}: """
+ f"""{tls_1_2_results[1]}""")
results = tls_1_2_results[0], description
elif tls_1_3_results[0] is not None and tls_1_2_results[0] is not None:
# Validate both results
- description = 'TLS 1.2' + (' not' if not tls_1_2_results[0] else
- '') + ' validated: ' + tls_1_2_results[1]
- description += '\nTLS 1.3' + (' not' if not tls_1_3_results[0] else
- '') + ' validated: ' + tls_1_3_results[1]
+ description = (f"""TLS 1.2 {'' if tls_1_2_results[0] else 'not '}"""
+ f"""validated on port {port}: """
+ f"""{tls_1_2_results[1]}""")
+ description += '\n'+(f"""TLS 1.3 {'' if tls_1_3_results[0] else 'not '}"""
+ f"""validated on port {port}: """
+ f"""{tls_1_3_results[1]}""")
results = tls_1_2_results[0] or tls_1_3_results[0], description
else:
- description = f'TLS 1.2 not validated: {tls_1_2_results[1]}'
- description += f'\nTLS 1.3 not validated: {tls_1_3_results[1]}'
+ description = (f"""TLS 1.2 not validated on port {port}: """
+ f"""{tls_1_2_results[1]}""")
+ description += '\n'+(f"""TLS 1.3 not validated on port {port}: """
+ f"""{tls_1_3_results[1]}""")
results = None, description
LOGGER.info('TLS server test results: ' + str(results))
return results
- def validate_tls_server(self, host, tls_version):
- cert_pem = self.get_public_certificate(host,
+ def validate_tls_server(self, host, tls_version, port=443):
+ cert_pem = self.get_public_certificate(host=host,
+ port=port,
validate_cert=False,
tls_version=tls_version)
if cert_pem:
@@ -430,13 +438,12 @@ def validate_tls_server(self, host, tls_version):
else:
key_valid = [0]
- sig_valid = self.validate_signature(host)
+ sig_valid = self.validate_signature(host=host, port=port)
# Check results
cert_valid = tr_valid[0] and key_valid[0] and sig_valid[0]
test_details = tr_valid[1] + '\n' + key_valid[1] + '\n' + sig_valid[1]
LOGGER.info('Certificate validated: ' + str(cert_valid))
- LOGGER.info('Test details:\n' + test_details)
return cert_valid, test_details
else:
LOGGER.info('Failed to resolve public certificate')
@@ -632,7 +639,7 @@ def get_non_tls_client_connection_ips(self, client_mac, capture_files):
# Packet is not ACK or SYN
src_ip = ipaddress.ip_address(
- packet['_source']['layers']['ip.src'][0])
+ packet['_source']['layers']['ip.src'][0])
src_subnet = ipaddress.ip_network(src_ip, strict=False)
subnet_with_mask = ipaddress.ip_network(
src_subnet, strict=False).supernet(new_prefix=24)
diff --git a/modules/test/tls/resources/report_template.jinja2 b/modules/test/tls/resources/report_template.jinja2
new file mode 100644
index 000000000..5680d9339
--- /dev/null
+++ b/modules/test/tls/resources/report_template.jinja2
@@ -0,0 +1,90 @@
+{% extends base_template %}
+{% block content %}
+{% if cert_info_data and subject_data %}
+
+
+
Certificate Information
+
+
+
+ {% for header in cert_table_headers%}
+ {{ header }}
+ {% endfor %}
+
+
+
+ {% for k,v in cert_info_data.items() %}
+
+ {{ k }}
+ {{ v }}
+
+ {% endfor %}
+
+
+
+
+
Subject Information
+
+
+
+ {% for header in cert_table_headers%}
+ {{ header }}
+ {% endfor %}
+
+
+
+ {% for k,v in subject_data.items() %}
+
+ {{ k }}
+ {{ v }}
+
+ {% endfor %}
+
+
+
+
+ {% if cert_ext %}
+ Certificate Extensions
+
+
+
+ Property
+ Value
+
+
+
+ {% for k,v in cert_ext.items()%}
+
+ {{ k }}
+ {{ v }}
+
+ {% endfor %}
+
+
+ {% endif %}
+{% elif ountbound_headers %}
+ Outbound Connections
+
+
+
+ {% for header in ountbound_headers%}
+ {{ header }}
+ {% endfor %}
+
+
+
+ {% for ip, port in outbound_conns%}
+
+ {{ip}}
+ {{port}}
+
+ {% endfor %}
+
+
+{% else %}
+
+
+ No TLS certificates found on the device
+
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/modules/test/tls/tls.Dockerfile b/modules/test/tls/tls.Dockerfile
index c448c8478..3d6d66544 100644
--- a/modules/test/tls/tls.Dockerfile
+++ b/modules/test/tls/tls.Dockerfile
@@ -51,3 +51,6 @@ RUN pip3 install -r /testrun/python/requirements-test.txt
# Create a directory inside the container to store the root certificates
RUN mkdir -p /testrun/root_certs
+
+# Copy Jinja template
+COPY $MODULE_DIR/resources/report_template.jinja2 $REPORT_TEMPLATE_PATH/
diff --git a/modules/ui/angular.json b/modules/ui/angular.json
index 28e0e9a36..d56b3b8ee 100644
--- a/modules/ui/angular.json
+++ b/modules/ui/angular.json
@@ -38,8 +38,8 @@
},
{
"type": "anyComponentStyle",
- "maximumWarning": "5kb",
- "maximumError": "6kb"
+ "maximumWarning": "6kb",
+ "maximumError": "7kb"
}
],
"outputHashing": "all"
diff --git a/modules/ui/package-lock.json b/modules/ui/package-lock.json
index b0ec71c07..1e4edf90f 100644
--- a/modules/ui/package-lock.json
+++ b/modules/ui/package-lock.json
@@ -67,12 +67,12 @@
}
},
"node_modules/@angular-devkit/architect": {
- "version": "0.1802.6",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.6.tgz",
- "integrity": "sha512-oF7cPFdTLxeuvXkK/opSdIxZ1E4LrBbmuytQ/nCoAGOaKBWdqvwagRZ6jVhaI0Gwu48rkcV7Zhesg/ESNnROdw==",
+ "version": "0.1802.14",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.14.tgz",
+ "integrity": "sha512-eplaGCXSlPwf1f4XwyzsYTd8/lJ0/Adm6XsODsBxvkZlIpLcps80/h2lH5MVJpoDREzIFu1BweDpYCoNK5yYZg==",
"dev": true,
"dependencies": {
- "@angular-devkit/core": "18.2.6",
+ "@angular-devkit/core": "18.2.14",
"rxjs": "7.8.1"
},
"engines": {
@@ -82,16 +82,16 @@
}
},
"node_modules/@angular-devkit/build-angular": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.6.tgz",
- "integrity": "sha512-u12cJZttgs5j7gICHWSmcaTCu0EFXEzKqI8nkYCwq2MtuJlAXiMQSXYuEP9OU3Go4vMAPtQh2kShyOWCX5b4EQ==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.14.tgz",
+ "integrity": "sha512-ycie4OhvNv8eNVqvq46pCIf6kB50xbMOdnAVqmlj+BaQjWbGjUQPjAmp4VGqeDZZ/lW82xkfTmJZxc6pYp7YdQ==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "2.3.0",
- "@angular-devkit/architect": "0.1802.6",
- "@angular-devkit/build-webpack": "0.1802.6",
- "@angular-devkit/core": "18.2.6",
- "@angular/build": "18.2.6",
+ "@angular-devkit/architect": "0.1802.14",
+ "@angular-devkit/build-webpack": "0.1802.14",
+ "@angular-devkit/core": "18.2.14",
+ "@angular/build": "18.2.14",
"@babel/core": "7.25.2",
"@babel/generator": "7.25.0",
"@babel/helper-annotate-as-pure": "7.24.7",
@@ -102,7 +102,7 @@
"@babel/preset-env": "7.25.3",
"@babel/runtime": "7.25.0",
"@discoveryjs/json-ext": "0.6.1",
- "@ngtools/webpack": "18.2.6",
+ "@ngtools/webpack": "18.2.14",
"@vitejs/plugin-basic-ssl": "1.1.0",
"ansi-colors": "4.1.3",
"autoprefixer": "10.4.20",
@@ -113,7 +113,7 @@
"css-loader": "7.1.2",
"esbuild-wasm": "0.23.0",
"fast-glob": "3.3.2",
- "http-proxy-middleware": "3.0.0",
+ "http-proxy-middleware": "3.0.3",
"https-proxy-agent": "7.0.5",
"istanbul-lib-instrument": "6.0.3",
"jsonc-parser": "3.3.1",
@@ -142,7 +142,6 @@
"terser": "5.31.6",
"tree-kill": "1.2.2",
"tslib": "2.6.3",
- "vite": "5.4.6",
"watchpack": "2.4.1",
"webpack": "5.94.0",
"webpack-dev-middleware": "7.4.2",
@@ -216,12 +215,12 @@
"dev": true
},
"node_modules/@angular-devkit/build-webpack": {
- "version": "0.1802.6",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.6.tgz",
- "integrity": "sha512-JMLcXFaitJplwZMKkqhbYirINCRD6eOPZuIGaIOVynXYGWgvJkLT9t5C2wm9HqSLtp1K7NcYG2Y7PtTVR4krnQ==",
+ "version": "0.1802.14",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.14.tgz",
+ "integrity": "sha512-cccne0SG4BaQHsKRRZCi/wMLJ7yFXrwvE8w+Kug3HdpJJoyH3FeG386EQuca/azslQlK+c5g4ywSZdXeNkGazA==",
"dev": true,
"dependencies": {
- "@angular-devkit/architect": "0.1802.6",
+ "@angular-devkit/architect": "0.1802.14",
"rxjs": "7.8.1"
},
"engines": {
@@ -235,9 +234,9 @@
}
},
"node_modules/@angular-devkit/core": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.6.tgz",
- "integrity": "sha512-la4CFvs5PcRWSkQ/H7TB5cPZirFVA9GoWk5LzIk8si6VjWBJRm8b3keKJoC9LlNeABRUIR5z0ocYkyQQUhdMfg==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.14.tgz",
+ "integrity": "sha512-UGIGOjXuOyCW+5S4tINu7e6LOu738CmTw3h7Ui1I8OzdTIYJcYJrei8sgrwDwOYADRal+p0MeMlnykH3TM5XBA==",
"dev": true,
"dependencies": {
"ajv": "8.17.1",
@@ -262,12 +261,12 @@
}
},
"node_modules/@angular-devkit/schematics": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.6.tgz",
- "integrity": "sha512-uIttrQ2cQ2PWAFFVPeCoNR8xvs7tPJ2i8gzqsIwYdge107xDC6u9CqfgmBqPDSFpWj+IiC2Jwcm8Z4HYKU4+7A==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.14.tgz",
+ "integrity": "sha512-mukjZIHHB7gWratq8fZwUq5WZ+1bF4feG/idXr1wgQ+/FqWjs2PP7HDesHVcPymmRulpTyCpB7TNB1O1fgnCpA==",
"dev": true,
"dependencies": {
- "@angular-devkit/core": "18.2.6",
+ "@angular-devkit/core": "18.2.14",
"jsonc-parser": "3.3.1",
"magic-string": "0.30.11",
"ora": "5.4.1",
@@ -290,19 +289,19 @@
}
},
"node_modules/@angular-eslint/bundled-angular-compiler": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.3.1.tgz",
- "integrity": "sha512-sikmkjfsXPpPTku1aQkQ1MNNEKGBgGGRvUN/WeNS9dhCJ4dxU3O7dZctt1aQWj+W3nbuUtDiimAWF5fZHGFE2Q==",
+ "version": "18.4.3",
+ "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.4.3.tgz",
+ "integrity": "sha512-zdrA8mR98X+U4YgHzUKmivRU+PxzwOL/j8G7eTOvBuq8GPzsP+hvak+tyxlgeGm9HsvpFj9ERHLtJ0xDUPs8fg==",
"dev": true
},
"node_modules/@angular-eslint/eslint-plugin": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-18.3.1.tgz",
- "integrity": "sha512-MP4Nm+SHboF8KdnN0KpPEGAaTTzDLPm3+S/4W3Mg8onqWCyadyd4mActh9mK/pvCj8TVlb/SW1zeTtdMYhwonw==",
+ "version": "18.4.3",
+ "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-18.4.3.tgz",
+ "integrity": "sha512-AyJbupiwTBR81P6T59v+aULEnPpZBCBxL2S5QFWfAhNCwWhcof4GihvdK2Z87yhvzDGeAzUFSWl/beJfeFa+PA==",
"dev": true,
"dependencies": {
- "@angular-eslint/bundled-angular-compiler": "18.3.1",
- "@angular-eslint/utils": "18.3.1"
+ "@angular-eslint/bundled-angular-compiler": "18.4.3",
+ "@angular-eslint/utils": "18.4.3"
},
"peerDependencies": {
"@typescript-eslint/utils": "^7.11.0 || ^8.0.0",
@@ -311,37 +310,36 @@
}
},
"node_modules/@angular-eslint/eslint-plugin-template": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-18.3.1.tgz",
- "integrity": "sha512-hBJ3+f7VSidvrtYaXH7Vp0sWvblA9jLK2c6uQzhYGWdEDUcTg7g7VI9ThW39WvMbHqkyzNE4PPOynK69cBEDGg==",
+ "version": "18.4.3",
+ "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-18.4.3.tgz",
+ "integrity": "sha512-ijGlX2N01ayMXTpeQivOA31AszO8OEbu9ZQUCxnu9AyMMhxyi2q50bujRChAvN9YXQfdQtbxuajxV6+aiWb5BQ==",
"dev": true,
"dependencies": {
- "@angular-eslint/bundled-angular-compiler": "18.3.1",
- "@angular-eslint/utils": "18.3.1",
- "aria-query": "5.3.0",
+ "@angular-eslint/bundled-angular-compiler": "18.4.3",
+ "@angular-eslint/utils": "18.4.3",
+ "aria-query": "5.3.2",
"axobject-query": "4.1.0"
},
"peerDependencies": {
+ "@typescript-eslint/types": "^7.11.0 || ^8.0.0",
"@typescript-eslint/utils": "^7.11.0 || ^8.0.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": "*"
}
},
"node_modules/@angular-eslint/schematics": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-18.3.1.tgz",
- "integrity": "sha512-BTsQHDu7LjvXannJTb5BqMPCFIHRNN94eRyb60VfjJxB/ZFtsbAQDFFOi5lEZsRsd4mBeUMuL9mW4IMcPtUQ9Q==",
+ "version": "18.4.3",
+ "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-18.4.3.tgz",
+ "integrity": "sha512-D5maKn5e6n58+8n7jLFLD4g+RGPOPeDSsvPc1sqial5tEKLxAJQJS9WZ28oef3bhkob6C60D+1H0mMmEEVvyVA==",
"dev": true,
"dependencies": {
- "@angular-eslint/eslint-plugin": "18.3.1",
- "@angular-eslint/eslint-plugin-template": "18.3.1",
- "ignore": "5.3.2",
+ "@angular-devkit/core": ">= 18.0.0 < 19.0.0",
+ "@angular-devkit/schematics": ">= 18.0.0 < 19.0.0",
+ "@angular-eslint/eslint-plugin": "18.4.3",
+ "@angular-eslint/eslint-plugin-template": "18.4.3",
+ "ignore": "6.0.2",
"semver": "7.6.3",
"strip-json-comments": "3.1.1"
- },
- "peerDependencies": {
- "@angular-devkit/core": ">= 18.0.0 < 19.0.0",
- "@angular-devkit/schematics": ">= 18.0.0 < 19.0.0"
}
},
"node_modules/@angular-eslint/template-parser": {
@@ -365,12 +363,12 @@
"dev": true
},
"node_modules/@angular-eslint/utils": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.3.1.tgz",
- "integrity": "sha512-sd9niZI7h9H2FQ7OLiQsLFBhjhRQTASh+Q0+4+hyjv9idbSHBJli8Gsi2fqj9zhtMKpAZFTrWzuLUpubJ9UYbA==",
+ "version": "18.4.3",
+ "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.4.3.tgz",
+ "integrity": "sha512-w0bJ9+ELAEiPBSTPPm9bvDngfu1d8JbzUhvs2vU+z7sIz/HMwUZT5S4naypj2kNN0gZYGYrW0lt+HIbW87zTAQ==",
"dev": true,
"dependencies": {
- "@angular-eslint/bundled-angular-compiler": "18.3.1"
+ "@angular-eslint/bundled-angular-compiler": "18.4.3"
},
"peerDependencies": {
"@typescript-eslint/utils": "^7.11.0 || ^8.0.0",
@@ -379,9 +377,9 @@
}
},
"node_modules/@angular/animations": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.6.tgz",
- "integrity": "sha512-vy9wy+Q9beiRxkEO8wNxFQ63AqAujGvk8AUHepxxIT7QNNc512TNKz8uH+feWDPO38Dm2obwYQHMGzs3WO7pUA==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.13.tgz",
+ "integrity": "sha512-rG5J5Ek5Hg+Tz2NjkNOaG6PupiNK/lPfophXpsR1t/nWujqnMWX2krahD/i6kgD+jNWNKCJCYSOVvCx/BHOtKA==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -389,17 +387,17 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/core": "18.2.6"
+ "@angular/core": "18.2.13"
}
},
"node_modules/@angular/build": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.6.tgz",
- "integrity": "sha512-TQzX6Mi7uXFvmz7+OVl4Za7WawYPcx+B5Ewm6IY/DdMyB9P/Z4tbKb1LO+ynWUXYwm7avXo6XQQ4m5ArDY5F/A==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.14.tgz",
+ "integrity": "sha512-9g24Oe/ZLULacW3hEpRCjSZIJPJTzN5BeFbA27epSV5NsrQOoeUGsEpRs90Zmt6eReO0fW1BGshWRoZtpSedcw==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "2.3.0",
- "@angular-devkit/architect": "0.1802.6",
+ "@angular-devkit/architect": "0.1802.14",
"@babel/core": "7.25.2",
"@babel/helper-annotate-as-pure": "7.24.7",
"@babel/helper-split-export-declaration": "7.24.7",
@@ -421,7 +419,7 @@
"rollup": "4.22.4",
"sass": "1.77.6",
"semver": "7.6.3",
- "vite": "5.4.6",
+ "vite": "5.4.14",
"watchpack": "2.4.1"
},
"engines": {
@@ -461,9 +459,9 @@
}
},
"node_modules/@angular/cdk": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.6.tgz",
- "integrity": "sha512-Gfq/iv4zhlKYpdQkDaBRwxI71NHNUHM1Cs1XhnZ0/oFct5HXvSv1RHRGTKqBJLLACaAPzZKXJ/UglLoyO5CNiQ==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.14.tgz",
+ "integrity": "sha512-vDyOh1lwjfVk9OqoroZAP8pf3xxKUvyl+TVR8nJxL4c5fOfUFkD7l94HaanqKSRwJcI2xiztuu92IVoHn8T33Q==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -477,17 +475,17 @@
}
},
"node_modules/@angular/cli": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.6.tgz",
- "integrity": "sha512-tdXsnV/w+Rgu8q0zFsLU5L9ImTVqrTol1vppHaQkJ/vuoHy+s8ZEbBqhVrO/ffosNb2xseUybGYvqMS4zkNQjg==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.14.tgz",
+ "integrity": "sha512-kWgRRQtJPkr8iwN7DMbTi3sXOnv7H5QhbU/GgD3nNX3D8YCSPmnby4PAE/P3wn7FsIK9JsSchsCt7MZ37Urh9A==",
"dev": true,
"dependencies": {
- "@angular-devkit/architect": "0.1802.6",
- "@angular-devkit/core": "18.2.6",
- "@angular-devkit/schematics": "18.2.6",
+ "@angular-devkit/architect": "0.1802.14",
+ "@angular-devkit/core": "18.2.14",
+ "@angular-devkit/schematics": "18.2.14",
"@inquirer/prompts": "5.3.8",
"@listr2/prompt-adapter-inquirer": "2.0.15",
- "@schematics/angular": "18.2.6",
+ "@schematics/angular": "18.2.14",
"@yarnpkg/lockfile": "1.1.0",
"ini": "4.1.3",
"jsonc-parser": "3.3.1",
@@ -510,9 +508,9 @@
}
},
"node_modules/@angular/common": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.6.tgz",
- "integrity": "sha512-89793ow+wrI1c7C6kyMbnweLNIZHzXthosxAEjipRZGBrqBYjvTtkE45Fl+5yBa3JO7bAhyGkUnEoyvWtZIAEA==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.13.tgz",
+ "integrity": "sha512-4ZqrNp1PoZo7VNvW+sbSc2CB2axP1sCH2wXl8B0wdjsj8JY1hF1OhuugwhpAHtGxqewed2kCXayE+ZJqSTV4jw==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -520,14 +518,14 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/core": "18.2.6",
+ "@angular/core": "18.2.13",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/compiler": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.6.tgz",
- "integrity": "sha512-3tX2/Qw+bZ8XzKitviH8jzNGyY0uohhehhBB57OJOCc+yr4ojy/7SYFnun1lSsRnDztdCE461641X4iQLCQ94w==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.13.tgz",
+ "integrity": "sha512-TzWcrkopyjFF+WeDr2cRe8CcHjU72KfYV3Sm2TkBkcXrkYX5sDjGWrBGrG3hRB4e4okqchrOCvm1MiTdy2vKMA==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -535,7 +533,7 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/core": "18.2.6"
+ "@angular/core": "18.2.13"
},
"peerDependenciesMeta": {
"@angular/core": {
@@ -544,14 +542,14 @@
}
},
"node_modules/@angular/compiler-cli": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.6.tgz",
- "integrity": "sha512-b5x9STfjNiNM/S0D+CnqRP9UOxPtSz1+RlCH5WdOMiW/p8j5p6dBix8YYgTe6Wg3OD7eItD2pnFQKgF/dWiopA==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.13.tgz",
+ "integrity": "sha512-DBSh4AQwkiJDSiVvJATRmjxf6wyUs9pwQLgaFdSlfuTRO+sdb0J2z1r3BYm8t0IqdoyXzdZq2YCH43EmyvD71g==",
"dev": true,
"dependencies": {
"@babel/core": "7.25.2",
"@jridgewell/sourcemap-codec": "^1.4.14",
- "chokidar": "^3.0.0",
+ "chokidar": "^4.0.0",
"convert-source-map": "^1.5.1",
"reflect-metadata": "^0.2.0",
"semver": "^7.0.0",
@@ -567,14 +565,14 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/compiler": "18.2.6",
+ "@angular/compiler": "18.2.13",
"typescript": ">=5.4 <5.6"
}
},
"node_modules/@angular/core": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.6.tgz",
- "integrity": "sha512-PjFad2j4YBwLVTw+0Te8CJCa/tV0W8caTHG8aOjj3ObdL6ihGI+FKnwerLc9RVzDFd14BOO4C6/+LbOQAh3Ltw==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.13.tgz",
+ "integrity": "sha512-8mbWHMgO95OuFV1Ejy4oKmbe9NOJ3WazQf/f7wks8Bck7pcihd0IKhlPBNjFllbF5o+04EYSwFhEtvEgjMDClA==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -587,9 +585,9 @@
}
},
"node_modules/@angular/forms": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.6.tgz",
- "integrity": "sha512-quGkUqTxlBaLB8C/RnpfFG57fdmNF5RQ+368N89Ma++2lpIsVAHaGZZn4yOyo3wNYaM2jBxNqaYxOzZNUl5Tig==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.13.tgz",
+ "integrity": "sha512-A67D867fu3DSBhdLWWZl/F5pr7v2+dRM2u3U7ZJ0ewh4a+sv+0yqWdJW+a8xIoiHxS+btGEJL2qAKJiH+MCFfg==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -597,22 +595,22 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/common": "18.2.6",
- "@angular/core": "18.2.6",
- "@angular/platform-browser": "18.2.6",
+ "@angular/common": "18.2.13",
+ "@angular/core": "18.2.13",
+ "@angular/platform-browser": "18.2.13",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/material": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.6.tgz",
- "integrity": "sha512-ObxC/vomSb9QF3vIztuiInQzws+D6u09Dhfx6uNFjtyICqxEFpF7+Qx7QVDWrsuXOgxZTKgacK8f46iV8hWUfg==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.14.tgz",
+ "integrity": "sha512-28pxzJP49Mymt664WnCtPkKeg7kXUsQKTKGf/Kl95rNTEdTJLbnlcc8wV0rT0yQNR7kXgpfBnG7h0ETLv/iu5Q==",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/animations": "^18.0.0 || ^19.0.0",
- "@angular/cdk": "18.2.6",
+ "@angular/cdk": "18.2.14",
"@angular/common": "^18.0.0 || ^19.0.0",
"@angular/core": "^18.0.0 || ^19.0.0",
"@angular/forms": "^18.0.0 || ^19.0.0",
@@ -621,9 +619,9 @@
}
},
"node_modules/@angular/platform-browser": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.6.tgz",
- "integrity": "sha512-RA8UMiYNLga+QMwpKcDw1357gYPfPyY/rmLeezMak//BbsENFYQOJ4Z6DBOBNiPlHxmBsUJMGaKdlpQhfCROyQ==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.13.tgz",
+ "integrity": "sha512-tu7ZzY6qD3ATdWFzcTcsAKe7M6cJeWbT/4/bF9unyGO3XBPcNYDKoiz10+7ap2PUd0fmPwvuvTvSNJiFEBnB8Q==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -631,9 +629,9 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/animations": "18.2.6",
- "@angular/common": "18.2.6",
- "@angular/core": "18.2.6"
+ "@angular/animations": "18.2.13",
+ "@angular/common": "18.2.13",
+ "@angular/core": "18.2.13"
},
"peerDependenciesMeta": {
"@angular/animations": {
@@ -642,9 +640,9 @@
}
},
"node_modules/@angular/platform-browser-dynamic": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.6.tgz",
- "integrity": "sha512-kGBU3FNc+DF9r33hwHZqiWoZgQbCDdEIucU0NCLCIg0Hw6/Q9Hr2ndjxQI+WynCPg0JeBn34jpouvpeJer3YDQ==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.13.tgz",
+ "integrity": "sha512-kbQCf9+8EpuJC7buBxhSiwBtXvjAwAKh6MznD6zd2pyCYqfY6gfRCZQRtK59IfgVtKmEONWI9grEyNIRoTmqJg==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -652,16 +650,16 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/common": "18.2.6",
- "@angular/compiler": "18.2.6",
- "@angular/core": "18.2.6",
- "@angular/platform-browser": "18.2.6"
+ "@angular/common": "18.2.13",
+ "@angular/compiler": "18.2.13",
+ "@angular/core": "18.2.13",
+ "@angular/platform-browser": "18.2.13"
}
},
"node_modules/@angular/router": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.6.tgz",
- "integrity": "sha512-t57Sqja8unHhZlPr+4CWnQacuox2M4p2pMHps+31wt337qH6mKf4jqDmK0dE/MFdRyKjT2a2E/2NwtxXxcWNuw==",
+ "version": "18.2.13",
+ "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.13.tgz",
+ "integrity": "sha512-VKmfgi/r/CkyBq9nChQ/ptmfu0JT/8ONnLVJ5H+SkFLRYJcIRyHLKjRihMCyVm6xM5yktOdCaW73NTQrFz7+bg==",
"dependencies": {
"tslib": "^2.3.0"
},
@@ -669,19 +667,20 @@
"node": "^18.19.1 || ^20.11.1 || >=22.0.0"
},
"peerDependencies": {
- "@angular/common": "18.2.6",
- "@angular/core": "18.2.6",
- "@angular/platform-browser": "18.2.6",
+ "@angular/common": "18.2.13",
+ "@angular/core": "18.2.13",
+ "@angular/platform-browser": "18.2.13",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@babel/code-frame": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
- "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"dev": true,
"dependencies": {
- "@babel/highlight": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
@@ -689,9 +688,9 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
- "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz",
+ "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -769,28 +768,15 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz",
- "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==",
- "dev": true,
- "dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
- "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
+ "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
"dev": true,
"dependencies": {
- "@babel/compat-data": "^7.25.2",
- "@babel/helper-validator-option": "^7.24.8",
- "browserslist": "^4.23.1",
+ "@babel/compat-data": "^7.26.5",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -808,17 +794,17 @@
}
},
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
- "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz",
+ "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==",
"dev": true,
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-member-expression-to-functions": "^7.24.8",
- "@babel/helper-optimise-call-expression": "^7.24.7",
- "@babel/helper-replace-supers": "^7.25.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/traverse": "^7.25.4",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
"semver": "^6.3.1"
},
"engines": {
@@ -828,6 +814,18 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -838,13 +836,13 @@
}
},
"node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz",
- "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
+ "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
"dev": true,
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "regexpu-core": "^5.3.1",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "regexpu-core": "^6.2.0",
"semver": "^6.3.1"
},
"engines": {
@@ -854,6 +852,18 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -864,9 +874,9 @@
}
},
"node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
- "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
+ "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
"dev": true,
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
@@ -880,41 +890,40 @@
}
},
"node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
- "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
+ "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
"dev": true,
"dependencies": {
- "@babel/traverse": "^7.24.8",
- "@babel/types": "^7.24.8"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
- "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
"dev": true,
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
- "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
"dev": true,
"dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-simple-access": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7",
- "@babel/traverse": "^7.25.2"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -924,35 +933,35 @@
}
},
"node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
- "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
+ "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.24.7"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
- "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
+ "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz",
- "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
"dev": true,
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-wrap-function": "^7.25.0",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-wrap-function": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -961,44 +970,43 @@
"@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/helper-replace-supers": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz",
- "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==",
+ "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
"dev": true,
"dependencies": {
- "@babel/helper-member-expression-to-functions": "^7.24.8",
- "@babel/helper-optimise-call-expression": "^7.24.7",
- "@babel/traverse": "^7.25.0"
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
}
},
- "node_modules/@babel/helper-simple-access": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
- "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz",
+ "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==",
"dev": true,
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/helper-member-expression-to-functions": "^7.25.9",
+ "@babel/helper-optimise-call-expression": "^7.25.9",
+ "@babel/traverse": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
}
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
- "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
+ "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
"dev": true,
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1017,66 +1025,66 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
- "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
- "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-wrap-function": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz",
- "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
+ "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
"dev": true,
"dependencies": {
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.0",
- "@babel/types": "^7.25.0"
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
- "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz",
+ "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==",
"dev": true,
"dependencies": {
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6"
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
- "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz",
+ "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==",
"dev": true,
"dependencies": {
- "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.25.9",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
@@ -1085,13 +1093,84 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@babel/parser": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
- "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
+ "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.25.6"
+ "@babel/types": "^7.26.7"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -1101,13 +1180,13 @@
}
},
"node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
- "version": "7.25.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz",
- "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
+ "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/traverse": "^7.25.3"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1117,12 +1196,12 @@
}
},
"node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz",
- "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
+ "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1132,12 +1211,12 @@
}
},
"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz",
- "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
+ "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1147,14 +1226,14 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz",
- "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/plugin-transform-optional-chaining": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1164,13 +1243,13 @@
}
},
"node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz",
- "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
+ "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1255,12 +1334,12 @@
}
},
"node_modules/@babel/plugin-syntax-import-assertions": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz",
- "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+ "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1427,12 +1506,12 @@
}
},
"node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz",
- "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
+ "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1477,12 +1556,12 @@
}
},
"node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz",
- "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
+ "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1492,12 +1571,12 @@
}
},
"node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz",
- "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
+ "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1507,13 +1586,13 @@
}
},
"node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz",
- "integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
+ "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
"dev": true,
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.25.4",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1523,14 +1602,13 @@
}
},
"node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz",
- "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==",
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+ "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
"dev": true,
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1540,16 +1618,16 @@
}
},
"node_modules/@babel/plugin-transform-classes": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz",
- "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
+ "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
"dev": true,
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-replace-supers": "^7.25.0",
- "@babel/traverse": "^7.25.4",
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
"globals": "^11.1.0"
},
"engines": {
@@ -1559,14 +1637,26 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz",
- "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
+ "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/template": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/template": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1576,12 +1666,12 @@
}
},
"node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz",
- "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
+ "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1591,13 +1681,13 @@
}
},
"node_modules/@babel/plugin-transform-dotall-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz",
- "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
+ "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
"dev": true,
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1607,12 +1697,12 @@
}
},
"node_modules/@babel/plugin-transform-duplicate-keys": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz",
- "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
+ "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1622,13 +1712,13 @@
}
},
"node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz",
- "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
"dev": true,
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.0",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1638,13 +1728,12 @@
}
},
"node_modules/@babel/plugin-transform-dynamic-import": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz",
- "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
+ "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1654,13 +1743,12 @@
}
},
"node_modules/@babel/plugin-transform-exponentiation-operator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz",
- "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
+ "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
"dev": true,
"dependencies": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1670,13 +1758,12 @@
}
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz",
- "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
+ "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1686,13 +1773,13 @@
}
},
"node_modules/@babel/plugin-transform-for-of": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz",
- "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
+ "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1702,14 +1789,14 @@
}
},
"node_modules/@babel/plugin-transform-function-name": {
- "version": "7.25.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz",
- "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
+ "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
"dev": true,
"dependencies": {
- "@babel/helper-compilation-targets": "^7.24.8",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/traverse": "^7.25.1"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1719,13 +1806,12 @@
}
},
"node_modules/@babel/plugin-transform-json-strings": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz",
- "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
+ "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-json-strings": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1735,12 +1821,12 @@
}
},
"node_modules/@babel/plugin-transform-literals": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz",
- "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
+ "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1750,13 +1836,12 @@
}
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz",
- "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
+ "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1766,12 +1851,12 @@
}
},
"node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz",
- "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
+ "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1781,13 +1866,13 @@
}
},
"node_modules/@babel/plugin-transform-modules-amd": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz",
- "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
+ "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
"dev": true,
"dependencies": {
- "@babel/helper-module-transforms": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1797,14 +1882,13 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz",
- "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==",
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz",
+ "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==",
"dev": true,
"dependencies": {
- "@babel/helper-module-transforms": "^7.24.8",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-simple-access": "^7.24.7"
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1814,15 +1898,15 @@
}
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz",
- "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
+ "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
"dev": true,
"dependencies": {
- "@babel/helper-module-transforms": "^7.25.0",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1832,13 +1916,13 @@
}
},
"node_modules/@babel/plugin-transform-modules-umd": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz",
- "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
+ "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
"dev": true,
"dependencies": {
- "@babel/helper-module-transforms": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-module-transforms": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1848,13 +1932,13 @@
}
},
"node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz",
- "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
+ "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
"dev": true,
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1864,12 +1948,12 @@
}
},
"node_modules/@babel/plugin-transform-new-target": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz",
- "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
+ "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1879,13 +1963,12 @@
}
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz",
- "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==",
+ "version": "7.26.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.6.tgz",
+ "integrity": "sha512-CKW8Vu+uUZneQCPtXmSBUC6NCAUdya26hWCElAWh5mVSlSRsmiCPUUDKb3Z0szng1hiAJa098Hkhg9o4SE35Qw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -1895,13 +1978,12 @@
}
},
"node_modules/@babel/plugin-transform-numeric-separator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz",
- "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
+ "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1911,15 +1993,14 @@
}
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz",
- "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
+ "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
"dev": true,
"dependencies": {
- "@babel/helper-compilation-targets": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.24.7"
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1929,13 +2010,13 @@
}
},
"node_modules/@babel/plugin-transform-object-super": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz",
- "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
+ "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-replace-supers": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-replace-supers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1945,13 +2026,12 @@
}
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz",
- "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
+ "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1961,14 +2041,13 @@
}
},
"node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz",
- "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
+ "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1978,12 +2057,12 @@
}
},
"node_modules/@babel/plugin-transform-parameters": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz",
- "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
+ "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1993,13 +2072,13 @@
}
},
"node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz",
- "integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
+ "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
"dev": true,
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.25.4",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2009,15 +2088,14 @@
}
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz",
- "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
+ "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
"dev": true,
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-create-class-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-create-class-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2026,13 +2104,25 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz",
- "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
+ "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2042,12 +2132,12 @@
}
},
"node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz",
- "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
+ "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.25.9",
"regenerator-transform": "^0.15.2"
},
"engines": {
@@ -2058,12 +2148,12 @@
}
},
"node_modules/@babel/plugin-transform-reserved-words": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz",
- "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
+ "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2102,12 +2192,12 @@
}
},
"node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz",
- "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
+ "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2117,13 +2207,13 @@
}
},
"node_modules/@babel/plugin-transform-spread": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz",
- "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
+ "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2133,12 +2223,12 @@
}
},
"node_modules/@babel/plugin-transform-sticky-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz",
- "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
+ "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2148,12 +2238,12 @@
}
},
"node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz",
- "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
+ "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2163,12 +2253,12 @@
}
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz",
- "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz",
+ "integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-plugin-utils": "^7.26.5"
},
"engines": {
"node": ">=6.9.0"
@@ -2178,12 +2268,12 @@
}
},
"node_modules/@babel/plugin-transform-unicode-escapes": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz",
- "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
+ "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2193,13 +2283,13 @@
}
},
"node_modules/@babel/plugin-transform-unicode-property-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz",
- "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
+ "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
"dev": true,
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2209,13 +2299,13 @@
}
},
"node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz",
- "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
+ "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
"dev": true,
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2225,13 +2315,13 @@
}
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz",
- "integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
+ "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
"dev": true,
"dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.25.2",
- "@babel/helper-plugin-utils": "^7.24.8"
+ "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2360,12 +2450,6 @@
"@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
}
},
- "node_modules/@babel/regjsgen": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
- "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==",
- "dev": true
- },
"node_modules/@babel/runtime": {
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
@@ -2379,30 +2463,30 @@
}
},
"node_modules/@babel/template": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
- "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
+ "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
"dev": true,
"dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/parser": "^7.25.0",
- "@babel/types": "^7.25.0"
+ "@babel/code-frame": "^7.25.9",
+ "@babel/parser": "^7.25.9",
+ "@babel/types": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
- "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz",
+ "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==",
"dev": true,
"dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.6",
- "@babel/parser": "^7.25.6",
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.5",
+ "@babel/parser": "^7.26.7",
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.7",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -2411,29 +2495,41 @@
}
},
"node_modules/@babel/traverse/node_modules/@babel/generator": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
- "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz",
+ "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.25.6",
+ "@babel/parser": "^7.26.5",
+ "@babel/types": "^7.26.5",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^2.5.1"
+ "jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/traverse/node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@babel/types": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
- "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+ "version": "7.26.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
+ "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
"dev": true,
"dependencies": {
- "@babel/helper-string-parser": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -2842,24 +2938,27 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
- "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
+ "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
"dev": true,
"dependencies": {
- "eslint-visitor-keys": "^3.3.0"
+ "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/regexpp": {
- "version": "4.11.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
- "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@@ -2929,10 +3028,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@eslint/eslintrc/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==",
+ "node_modules/@eslint/eslintrc/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,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@eslint/eslintrc/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==",
"dev": true
},
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
@@ -3118,9 +3226,9 @@
}
},
"node_modules/@inquirer/figures": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.6.tgz",
- "integrity": "sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==",
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.10.tgz",
+ "integrity": "sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==",
"dev": true,
"engines": {
"node": ">=18"
@@ -3350,9 +3458,9 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
"dev": true,
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
@@ -3424,9 +3532,9 @@
}
},
"node_modules/@jsonjoy.com/json-pack": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz",
- "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz",
+ "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==",
"dev": true,
"dependencies": {
"@jsonjoy.com/base64": "^1.1.1",
@@ -3446,9 +3554,9 @@
}
},
"node_modules/@jsonjoy.com/util": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz",
- "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz",
+ "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==",
"dev": true,
"engines": {
"node": ">=10.0"
@@ -3639,11 +3747,10 @@
]
},
"node_modules/@ngrx/component-store": {
- "version": "18.0.2",
- "resolved": "https://registry.npmjs.org/@ngrx/component-store/-/component-store-18.0.2.tgz",
- "integrity": "sha512-IB7ZKFqjDt4duQbfYqXxAOKf9Si9O1HFodqbNCSgi7gnovK/frf/H429a+lYOyItPcpno3ECom6/1k8pE8fWlg==",
+ "version": "18.1.1",
+ "resolved": "https://registry.npmjs.org/@ngrx/component-store/-/component-store-18.1.1.tgz",
+ "integrity": "sha512-+FDd44D+unx/eE/7qCyK1IDsTu8503JOnj3lEhL9f9TDmE4arDNqeNx/8Sh3V3HDkH7mVC9iV0c538ACGlvWIA==",
"dependencies": {
- "@ngrx/operators": "18.0.1",
"tslib": "^2.0.0"
},
"peerDependencies": {
@@ -3652,34 +3759,22 @@
}
},
"node_modules/@ngrx/effects": {
- "version": "18.0.2",
- "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-18.0.2.tgz",
- "integrity": "sha512-YojXcOD9Lsq4kl2HCjENccyUM/mOlgBdtddsg9j/ojzSUgu3ZuBVKLN3atrL2TJYkbMX1MN0RzafSkL3TPGFIA==",
+ "version": "18.1.1",
+ "resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-18.1.1.tgz",
+ "integrity": "sha512-XXob8kYEvYMaZwgHtrrTW0XZargbu5PloEpNHLnzB8jPk0yWEw6keryxaF09Ylws1779MWvMmF/YP2rPl04nHQ==",
"dependencies": {
- "@ngrx/operators": "18.0.1",
"tslib": "^2.0.0"
},
"peerDependencies": {
"@angular/core": "^18.0.0",
- "@ngrx/store": "18.0.2",
+ "@ngrx/store": "18.1.1",
"rxjs": "^6.5.3 || ^7.5.0"
}
},
- "node_modules/@ngrx/operators": {
- "version": "18.0.1",
- "resolved": "https://registry.npmjs.org/@ngrx/operators/-/operators-18.0.1.tgz",
- "integrity": "sha512-M+QMrHNKgcuiLaRGZxJ4aQi5/OCRfKC4+T/63dsHyLFZ53/FFpF6a/ytSO1Q+tzOplZ5o99S+i8FVaZqNQ3LmQ==",
- "dependencies": {
- "tslib": "^2.3.0"
- },
- "peerDependencies": {
- "rxjs": "^6.5.3 || ^7.4.0"
- }
- },
"node_modules/@ngrx/store": {
- "version": "18.0.2",
- "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-18.0.2.tgz",
- "integrity": "sha512-ajwv0+njsO4vzArp9esnFvs1wyUb1U1W8E8LSCKrcW2hWWo9o1Pezj+JRsdQwatxHfrrPFuTDyajsl6GQM/JSA==",
+ "version": "18.1.1",
+ "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-18.1.1.tgz",
+ "integrity": "sha512-K0v1akJ2sEnIeb1AUA064+ksgRgbMgVG9HbSsLBxENbFjK2ZvKRxo1bpOw6WHW9+hyDTlhZGl7+gUtjmo3497g==",
"dependencies": {
"tslib": "^2.0.0"
},
@@ -3689,9 +3784,9 @@
}
},
"node_modules/@ngtools/webpack": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.6.tgz",
- "integrity": "sha512-7HwOPE1EOgcHnpt4brSiT8G2CcXB50G0+CbCBaKGy4LYCG3Y3mrlzF5Fup9HvMJ6Tzqd62RqzpKKYBiGUT7hxg==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.14.tgz",
+ "integrity": "sha512-rT+Y4WR8QTVsijtb+YRqHcPTpd1ZiwRbklQXRTxU0YGFHpxpi+bhjmY8FjpPoAtdPO1Lg3l3KIZPZa0thG0FNg==",
"dev": true,
"engines": {
"node": "^18.19.1 || ^20.11.1 || >=22.0.0",
@@ -4203,13 +4298,13 @@
]
},
"node_modules/@schematics/angular": {
- "version": "18.2.6",
- "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.6.tgz",
- "integrity": "sha512-Y988EoOEQDLEyHu3414T6AeVUyx21AexBHQNbUNQkK8cxlxyB6m1eH1cx6vFgLRFUTsLVv+C6Ln/ICNTfLcG4A==",
+ "version": "18.2.14",
+ "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.14.tgz",
+ "integrity": "sha512-CHh6ew2Az71UlvVcnYeuMEwjwkZqR7y/9ebLzFRvczC71ZL8qPVBpBTVGbCpGBd54VEbCZVWRxBQoZZ5LP/aBw==",
"dev": true,
"dependencies": {
- "@angular-devkit/core": "18.2.6",
- "@angular-devkit/schematics": "18.2.6",
+ "@angular-devkit/core": "18.2.14",
+ "@angular-devkit/schematics": "18.2.14",
"jsonc-parser": "3.3.1"
},
"engines": {
@@ -4240,12 +4335,12 @@
}
},
"node_modules/@sigstore/protobuf-specs": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz",
- "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==",
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.3.tgz",
+ "integrity": "sha512-RpacQhBlwpBWd7KEJsRKcBQalbV28fvkxwTOJIqhIuDysMMaJW47V4OqW30iJB9uRpqOSxxEAQFdr8tTattReQ==",
"dev": true,
"engines": {
- "node": "^16.14.0 || >=18.0.0"
+ "node": "^18.17.0 || >=20.5.0"
}
},
"node_modules/@sigstore/sign": {
@@ -4370,12 +4465,6 @@
"@types/node": "*"
}
},
- "node_modules/@types/cookie": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
- "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
- "dev": true
- },
"node_modules/@types/cors": {
"version": "2.8.17",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
@@ -4410,9 +4499,9 @@
}
},
"node_modules/@types/express-serve-static-core": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz",
- "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==",
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
+ "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
"dev": true,
"dependencies": {
"@types/node": "*",
@@ -4476,12 +4565,12 @@
}
},
"node_modules/@types/node": {
- "version": "22.7.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
- "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==",
+ "version": "22.12.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz",
+ "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==",
"dev": true,
"dependencies": {
- "undici-types": "~6.19.2"
+ "undici-types": "~6.20.0"
}
},
"node_modules/@types/node-forge": {
@@ -4494,9 +4583,9 @@
}
},
"node_modules/@types/qs": {
- "version": "6.9.16",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz",
- "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==",
+ "version": "6.9.18",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz",
+ "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==",
"dev": true
},
"node_modules/@types/range-parser": {
@@ -4557,29 +4646,29 @@
"dev": true
},
"node_modules/@types/ws": {
- "version": "8.5.12",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz",
- "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==",
+ "version": "8.5.14",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
+ "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.0.tgz",
- "integrity": "sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.22.0.tgz",
+ "integrity": "sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.8.0",
- "@typescript-eslint/type-utils": "8.8.0",
- "@typescript-eslint/utils": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0",
+ "@typescript-eslint/scope-manager": "8.22.0",
+ "@typescript-eslint/type-utils": "8.22.0",
+ "@typescript-eslint/utils": "8.22.0",
+ "@typescript-eslint/visitor-keys": "8.22.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4590,12 +4679,17 @@
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/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,
+ "engines": {
+ "node": ">= 4"
}
},
"node_modules/@typescript-eslint/experimental-utils": {
@@ -4710,15 +4804,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.0.tgz",
- "integrity": "sha512-uEFUsgR+tl8GmzmLjRqz+VrDv4eoaMqMXW7ruXfgThaAShO9JTciKpEsB+TvnfFfbg5IpujgMXVV36gOJRLtZg==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.22.0.tgz",
+ "integrity": "sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "8.8.0",
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/typescript-estree": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0",
+ "@typescript-eslint/scope-manager": "8.22.0",
+ "@typescript-eslint/types": "8.22.0",
+ "@typescript-eslint/typescript-estree": "8.22.0",
+ "@typescript-eslint/visitor-keys": "8.22.0",
"debug": "^4.3.4"
},
"engines": {
@@ -4729,22 +4823,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
- "integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz",
+ "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0"
+ "@typescript-eslint/types": "8.22.0",
+ "@typescript-eslint/visitor-keys": "8.22.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4755,15 +4845,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.0.tgz",
- "integrity": "sha512-IKwJSS7bCqyCeG4NVGxnOP6lLT9Okc3Zj8hLO96bpMkJab+10HIfJbMouLrlpyOr3yrQ1cA413YPFiGd1mW9/Q==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.22.0.tgz",
+ "integrity": "sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.8.0",
- "@typescript-eslint/utils": "8.8.0",
+ "@typescript-eslint/typescript-estree": "8.22.0",
+ "@typescript-eslint/utils": "8.22.0",
"debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4772,16 +4862,15 @@
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
- "integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz",
+ "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==",
"dev": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4792,19 +4881,19 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
- "integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz",
+ "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/visitor-keys": "8.8.0",
+ "@typescript-eslint/types": "8.22.0",
+ "@typescript-eslint/visitor-keys": "8.22.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
"minimatch": "^9.0.4",
"semver": "^7.6.0",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4813,22 +4902,20 @@
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
- "integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz",
+ "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "8.8.0",
- "@typescript-eslint/types": "8.8.0",
- "@typescript-eslint/typescript-estree": "8.8.0"
+ "@typescript-eslint/scope-manager": "8.22.0",
+ "@typescript-eslint/types": "8.22.0",
+ "@typescript-eslint/typescript-estree": "8.22.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4838,17 +4925,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0"
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
- "integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
+ "version": "8.22.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz",
+ "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "8.8.0",
- "eslint-visitor-keys": "^3.4.3"
+ "@typescript-eslint/types": "8.22.0",
+ "eslint-visitor-keys": "^4.2.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -4858,10 +4946,22 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
"node_modules/@ungap/structured-clone": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
- "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
"dev": true
},
"node_modules/@vitejs/plugin-basic-ssl": {
@@ -4877,148 +4977,148 @@
}
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
- "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"dev": true,
"dependencies": {
- "@webassemblyjs/helper-numbers": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
}
},
"node_modules/@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
- "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
"dev": true
},
"node_modules/@webassemblyjs/helper-api-error": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
- "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
"dev": true
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
- "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
"dev": true
},
"node_modules/@webassemblyjs/helper-numbers": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
- "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"dev": true,
"dependencies": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.6",
- "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
- "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
"dev": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
- "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-buffer": "1.12.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.12.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
- "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"dev": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
},
"node_modules/@webassemblyjs/leb128": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
- "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"dev": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/utf8": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
- "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
"dev": true
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
- "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-buffer": "1.12.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/helper-wasm-section": "1.12.1",
- "@webassemblyjs/wasm-gen": "1.12.1",
- "@webassemblyjs/wasm-opt": "1.12.1",
- "@webassemblyjs/wasm-parser": "1.12.1",
- "@webassemblyjs/wast-printer": "1.12.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
- "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/ieee754": "1.11.6",
- "@webassemblyjs/leb128": "1.11.6",
- "@webassemblyjs/utf8": "1.11.6"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
- "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-buffer": "1.12.1",
- "@webassemblyjs/wasm-gen": "1.12.1",
- "@webassemblyjs/wasm-parser": "1.12.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
- "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-api-error": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/ieee754": "1.11.6",
- "@webassemblyjs/leb128": "1.11.6",
- "@webassemblyjs/utf8": "1.11.6"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
- "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
}
},
@@ -5062,10 +5162,19 @@
"node": ">= 0.6"
}
},
+ "node_modules/accepts/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -5120,13 +5229,10 @@
}
},
"node_modules/agent-base": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
- "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
"dev": true,
- "dependencies": {
- "debug": "^4.3.4"
- },
"engines": {
"node": ">= 14"
}
@@ -5235,15 +5341,18 @@
}
},
"node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": {
- "color-convert": "^1.9.0"
+ "color-convert": "^2.0.1"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/anymatch": {
@@ -5278,12 +5387,12 @@
"dev": true
},
"node_modules/aria-query": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
- "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
+ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
"dev": true,
- "dependencies": {
- "dequal": "^2.0.3"
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/array-flatten": {
@@ -5365,13 +5474,13 @@
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.11",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz",
- "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==",
+ "version": "0.4.12",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
+ "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.22.6",
- "@babel/helper-define-polyfill-provider": "^0.6.2",
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
"semver": "^6.3.1"
},
"peerDependencies": {
@@ -5401,12 +5510,12 @@
}
},
"node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz",
- "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
+ "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
"dev": true,
"dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.2"
+ "@babel/helper-define-polyfill-provider": "^0.6.3"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -5522,9 +5631,9 @@
"dev": true
},
"node_modules/bonjour-service": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz",
- "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz",
+ "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -5559,9 +5668,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.24.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
- "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
"dev": true,
"funding": [
{
@@ -5578,10 +5687,10 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001663",
- "electron-to-chromium": "^1.5.28",
- "node-releases": "^2.0.18",
- "update-browserslist-db": "^1.1.0"
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
},
"bin": {
"browserslist": "cli.js"
@@ -5691,17 +5800,27 @@
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true
},
- "node_modules/call-bind": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
- "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
+ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"dev": true,
"dependencies": {
- "es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "set-function-length": "^1.2.1"
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
@@ -5720,9 +5839,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001664",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
- "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==",
+ "version": "1.0.30001696",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz",
+ "integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==",
"dev": true,
"funding": [
{
@@ -5740,17 +5859,19 @@
]
},
"node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chardet": {
@@ -5760,27 +5881,18 @@
"dev": true
},
"node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
"dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
+ "readdirp": "^4.0.1"
},
"engines": {
- "node": ">= 8.10.0"
+ "node": ">= 14.16.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
}
},
"node_modules/chownr": {
@@ -5876,39 +5988,6 @@
"node": ">=12"
}
},
- "node_modules/cliui/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/cliui/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/cliui/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"node_modules/cliui/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -5978,19 +6057,34 @@
"node": ">=6"
}
},
+ "node_modules/clone-deep/node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": {
- "color-name": "1.1.3"
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
}
},
"node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/colorette": {
@@ -6042,32 +6136,23 @@
}
},
"node_modules/compression": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
- "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz",
+ "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==",
"dev": true,
"dependencies": {
- "accepts": "~1.3.5",
- "bytes": "3.0.0",
- "compressible": "~2.0.16",
+ "bytes": "3.1.2",
+ "compressible": "~2.0.18",
"debug": "2.6.9",
+ "negotiator": "~0.6.4",
"on-headers": "~1.0.2",
- "safe-buffer": "5.1.2",
+ "safe-buffer": "5.2.1",
"vary": "~1.1.2"
},
"engines": {
"node": ">= 0.8.0"
}
},
- "node_modules/compression/node_modules/bytes": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/compression/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -6083,12 +6168,6 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
- "node_modules/compression/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -6225,25 +6304,13 @@
"webpack": "^5.1.0"
}
},
- "node_modules/copy-webpack-plugin/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,
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/core-js-compat": {
- "version": "3.38.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
- "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==",
+ "version": "3.40.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz",
+ "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==",
"dev": true,
"dependencies": {
- "browserslist": "^4.23.3"
+ "browserslist": "^4.24.3"
},
"funding": {
"type": "opencollective",
@@ -6299,6 +6366,7 @@
"version": "0.0.24",
"resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz",
"integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==",
+ "deprecated": "Ownership of Critters has moved to the Nuxt team, who will be maintaining the project going forward. If you'd like to keep using Critters, please switch to the actively-maintained fork at https://github.com/danielroe/beasties",
"dev": true,
"dependencies": {
"chalk": "^4.1.0",
@@ -6310,85 +6378,15 @@
"postcss-media-query-parser": "^0.2.3"
}
},
- "node_modules/critters/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "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,
"dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/critters/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/critters/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/critters/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/critters/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/critters/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
},
"engines": {
"node": ">= 8"
@@ -6485,9 +6483,9 @@
}
},
"node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dependencies": {
"ms": "^2.1.3"
},
@@ -6558,23 +6556,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/define-data-property": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
- "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
- "dev": true,
- "dependencies": {
- "es-define-property": "^1.0.0",
- "es-errors": "^1.3.0",
- "gopd": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/define-lazy-prop": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
@@ -6596,15 +6577,6 @@
"node": ">= 0.8"
}
},
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@@ -6720,9 +6692,9 @@
}
},
"node_modules/domutils": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
- "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
"dev": true,
"dependencies": {
"dom-serializer": "^2.0.0",
@@ -6733,6 +6705,20 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/duplexify": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz",
@@ -6757,9 +6743,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
- "version": "1.5.30",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.30.tgz",
- "integrity": "sha512-sXI35EBN4lYxzc/pIGorlymYNzDBOqkSlVRe6MkgBsW/hW1tpC/HDJ2fjG7XnjakzfLEuvdmux0Mjs6jHq4UOA==",
+ "version": "1.5.90",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz",
+ "integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==",
"dev": true
},
"node_modules/emoji-regex": {
@@ -6818,12 +6804,11 @@
}
},
"node_modules/engine.io": {
- "version": "6.6.2",
- "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz",
- "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==",
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
+ "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
"dev": true,
"dependencies": {
- "@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
"@types/node": ">=10.0.0",
"accepts": "~1.3.4",
@@ -6847,6 +6832,23 @@
"node": ">=10.0.0"
}
},
+ "node_modules/engine.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/engine.io/node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
@@ -6869,9 +6871,9 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.17.1",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
- "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
+ "version": "5.18.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz",
+ "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -6895,12 +6897,15 @@
}
},
"node_modules/ent": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz",
- "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==",
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz",
+ "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==",
"dev": true,
"dependencies": {
- "punycode": "^1.4.1"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "punycode": "^1.4.1",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -6968,13 +6973,10 @@
}
},
"node_modules/es-define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
- "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
- "dependencies": {
- "get-intrinsic": "^1.2.4"
- },
"engines": {
"node": ">= 0.4"
}
@@ -6989,11 +6991,23 @@
}
},
"node_modules/es-module-lexer": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
- "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
+ "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
"dev": true
},
+ "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==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/esbuild": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz",
@@ -7061,18 +7075,22 @@
"dev": true
},
"node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true,
"engines": {
- "node": ">=0.8.0"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint": {
"version": "8.57.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
@@ -7137,9 +7155,9 @@
}
},
"node_modules/eslint-plugin-prettier": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz",
- "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz",
+ "integrity": "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==",
"dev": true,
"dependencies": {
"prettier-linter-helpers": "^1.0.0",
@@ -7167,9 +7185,9 @@
}
},
"node_modules/eslint-scope": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz",
- "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==",
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
+ "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
@@ -7234,21 +7252,6 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/eslint/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/eslint/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -7259,52 +7262,6 @@
"concat-map": "0.0.1"
}
},
- "node_modules/eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/eslint/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/eslint/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,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/eslint/node_modules/eslint-scope": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
@@ -7321,18 +7278,6 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint/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,
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/eslint/node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
@@ -7348,13 +7293,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "node_modules/eslint/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,
"engines": {
- "node": ">=8"
+ "node": ">= 4"
}
},
"node_modules/eslint/node_modules/json-schema-traverse": {
@@ -7375,18 +7320,6 @@
"node": "*"
}
},
- "node_modules/eslint/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/eslint/node_modules/type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
@@ -7546,9 +7479,9 @@
"dev": true
},
"node_modules/express": {
- "version": "4.21.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz",
- "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"dev": true,
"dependencies": {
"accepts": "~1.3.8",
@@ -7570,7 +7503,7 @@
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
- "path-to-regexp": "0.1.10",
+ "path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7",
"qs": "6.13.0",
"range-parser": "~1.2.1",
@@ -7585,6 +7518,10 @@
},
"engines": {
"node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/express/node_modules/cookie": {
@@ -7695,6 +7632,18 @@
"node": ">=8.6.0"
}
},
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"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",
@@ -7708,15 +7657,25 @@
"dev": true
},
"node_modules/fast-uri": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz",
- "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==",
- "dev": true
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ]
},
"node_modules/fastq": {
- "version": "1.17.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
- "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
+ "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
"dev": true,
"dependencies": {
"reusify": "^1.0.4"
@@ -7859,9 +7818,9 @@
}
},
"node_modules/flatted": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
- "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
+ "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
"dev": true
},
"node_modules/follow-redirects": {
@@ -8010,9 +7969,9 @@
}
},
"node_modules/get-east-asian-width": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
- "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
+ "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==",
"dev": true,
"engines": {
"node": ">=18"
@@ -8022,16 +7981,21 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
- "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
+ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
"dev": true,
"dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "hasown": "^2.0.0"
+ "get-proto": "^1.0.0",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -8040,6 +8004,19 @@
"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==",
+ "dev": true,
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -8073,15 +8050,15 @@
}
},
"node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "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,
"dependencies": {
- "is-glob": "^4.0.1"
+ "is-glob": "^4.0.3"
},
"engines": {
- "node": ">= 6"
+ "node": ">=10.13.0"
}
},
"node_modules/glob-to-regexp": {
@@ -8139,13 +8116,22 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/globby/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,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
- "dependencies": {
- "get-intrinsic": "^1.1.3"
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -8191,30 +8177,18 @@
}
},
"node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
- "node": ">=4"
- }
- },
- "node_modules/has-property-descriptors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
- "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
- "dev": true,
- "dependencies": {
- "es-define-property": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=8"
}
},
- "node_modules/has-proto": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
- "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "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==",
"dev": true,
"engines": {
"node": ">= 0.4"
@@ -8223,11 +8197,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -8395,9 +8372,9 @@
}
},
"node_modules/http-parser-js": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
- "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==",
+ "version": "0.5.9",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz",
+ "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==",
"dev": true
},
"node_modules/http-proxy": {
@@ -8428,17 +8405,17 @@
}
},
"node_modules/http-proxy-middleware": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.0.tgz",
- "integrity": "sha512-36AV1fIaI2cWRzHo+rbcxhe3M3jUDCNzc4D5zRl57sEWRAxdXYtw7FSQKYY6PDKssiAKjLYypbssHk+xs/kMXw==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz",
+ "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==",
"dev": true,
"dependencies": {
- "@types/http-proxy": "^1.17.10",
- "debug": "^4.3.4",
+ "@types/http-proxy": "^1.17.15",
+ "debug": "^4.3.6",
"http-proxy": "^1.18.1",
- "is-glob": "^4.0.1",
- "is-plain-obj": "^3.0.0",
- "micromatch": "^4.0.5"
+ "is-glob": "^4.0.3",
+ "is-plain-object": "^5.0.0",
+ "micromatch": "^4.0.8"
},
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -8519,9 +8496,9 @@
]
},
"node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz",
+ "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -8657,9 +8634,9 @@
}
},
"node_modules/is-core-module": {
- "version": "2.15.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
- "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"dev": true,
"dependencies": {
"hasown": "^2.0.2"
@@ -8795,15 +8772,30 @@
}
},
"node_modules/is-plain-object": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
- "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"dev": true,
"dependencies": {
- "isobject": "^3.0.1"
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-stream": {
@@ -8923,27 +8915,6 @@
"node": ">=10"
}
},
- "node_modules/istanbul-lib-report/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/istanbul-lib-source-maps": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
@@ -9015,15 +8986,6 @@
"node": ">= 10.13.0"
}
},
- "node_modules/jest-worker/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/jest-worker/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -9040,9 +9002,9 @@
}
},
"node_modules/jiti": {
- "version": "1.21.6",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
- "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"dev": true,
"bin": {
"jiti": "bin/jiti.js"
@@ -9314,21 +9276,6 @@
"source-map-support": "^0.5.5"
}
},
- "node_modules/karma/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/karma/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -9339,6 +9286,30 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/karma/node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
"node_modules/karma/node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -9350,23 +9321,32 @@
"wrap-ansi": "^7.0.0"
}
},
- "node_modules/karma/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "node_modules/karma/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/karma/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"dependencies": {
- "color-name": "~1.1.4"
+ "is-glob": "^4.0.1"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">= 6"
}
},
- "node_modules/karma/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "node_modules/karma/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/karma/node_modules/emoji-regex": {
"version": "8.0.0",
@@ -9395,6 +9375,30 @@
"node": "*"
}
},
+ "node_modules/karma/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/karma/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
"node_modules/karma/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -9819,74 +9823,125 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/log-symbols/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "node_modules/log-update": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
"dev": true,
"dependencies": {
- "color-convert": "^2.0.1"
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=18"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/log-symbols/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "node_modules/log-update/node_modules/ansi-escapes": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz",
+ "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==",
"dev": true,
"dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "environment": "^1.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=18"
},
"funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/log-symbols/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "node_modules/log-update/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
"engines": {
- "node": ">=7.0.0"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
- "node_modules/log-symbols/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/log-symbols/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
"engines": {
- "node": ">=8"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/log-symbols/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz",
+ "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==",
"dev": true,
"dependencies": {
- "has-flag": "^4.0.0"
+ "get-east-asian-width": "^1.0.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz",
+ "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/wrap-ansi": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz",
+ "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/log-update": {
@@ -10083,6 +10138,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/loglevel-colored-level-prefix/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
"node_modules/loglevel-colored-level-prefix/node_modules/strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -10160,6 +10224,15 @@
"node": "^16.14.0 || >=18.0.0"
}
},
+ "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==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -10170,9 +10243,9 @@
}
},
"node_modules/memfs": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.12.0.tgz",
- "integrity": "sha512-74wDsex5tQDSClVkeK1vtxqYCAgCoXxx+K4NSHzgU/muYVYByFqa+0RnrPO9NM6naWm1+G9JmZ0p6QHhXmeYfA==",
+ "version": "4.17.0",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.0.tgz",
+ "integrity": "sha512-4eirfZ7thblFmqFjywlTmuWVSvccHAJbn1r8qQLzmTO11qcqpohOjmY2mFce6x7x7WtskzRqApPD0hv+Oa74jg==",
"dev": true,
"dependencies": {
"@jsonjoy.com/json-pack": "^1.0.3",
@@ -10601,9 +10674,9 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/msgpackr": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz",
- "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==",
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz",
+ "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==",
"dev": true,
"optionalDependencies": {
"msgpackr-extract": "^3.0.2"
@@ -10654,9 +10727,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true,
"funding": [
{
@@ -10708,9 +10781,9 @@
}
},
"node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
"dev": true,
"engines": {
"node": ">= 0.6"
@@ -10787,9 +10860,9 @@
}
},
"node_modules/node-gyp": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz",
- "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==",
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz",
+ "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==",
"dev": true,
"dependencies": {
"env-paths": "^2.2.0",
@@ -10811,9 +10884,9 @@
}
},
"node_modules/node-gyp-build": {
- "version": "4.8.2",
- "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz",
- "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==",
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
"dev": true,
"optional": true,
"bin": {
@@ -10881,9 +10954,9 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
- "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true
},
"node_modules/nopt": {
@@ -11070,9 +11143,9 @@
}
},
"node_modules/object-inspect": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
- "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
+ "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"dev": true,
"engines": {
"node": ">= 0.4"
@@ -11189,37 +11262,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/ora/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/ora/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
"node_modules/ora/node_modules/cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -11232,33 +11274,6 @@
"node": ">=8"
}
},
- "node_modules/ora/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/ora/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/ora/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ora/node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -11293,17 +11308,11 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
- "node_modules/ora/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
+ "node_modules/ordered-binary": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz",
+ "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==",
+ "dev": true
},
"node_modules/ordered-binary": {
"version": "1.5.2",
@@ -11366,9 +11375,9 @@
}
},
"node_modules/p-retry": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz",
- "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz",
+ "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==",
"dev": true,
"dependencies": {
"@types/retry": "0.12.2",
@@ -11474,12 +11483,12 @@
}
},
"node_modules/parse5": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
- "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
+ "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
"devOptional": true,
"dependencies": {
- "entities": "^4.4.0"
+ "entities": "^4.5.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
@@ -11575,9 +11584,9 @@
"dev": true
},
"node_modules/path-to-regexp": {
- "version": "0.1.10",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
- "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"dev": true
},
"node_modules/path-type": {
@@ -11593,9 +11602,9 @@
}
},
"node_modules/picocolors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
- "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true
},
"node_modules/picomatch": {
@@ -11804,13 +11813,13 @@
}
},
"node_modules/postcss-modules-local-by-default": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz",
- "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
+ "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
"dev": true,
"dependencies": {
"icss-utils": "^5.0.0",
- "postcss-selector-parser": "^6.0.2",
+ "postcss-selector-parser": "^7.0.0",
"postcss-value-parser": "^4.1.0"
},
"engines": {
@@ -11821,12 +11830,12 @@
}
},
"node_modules/postcss-modules-scope": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz",
- "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+ "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
"dev": true,
"dependencies": {
- "postcss-selector-parser": "^6.0.4"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
"node": "^10 || ^12 || >= 14"
@@ -11851,9 +11860,9 @@
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
+ "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
@@ -11879,9 +11888,9 @@
}
},
"node_modules/prettier": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
- "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
+ "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -12080,21 +12089,6 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/prettier-eslint/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/prettier-eslint/node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -12114,56 +12108,11 @@
"concat-map": "0.0.1"
}
},
- "node_modules/prettier-eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/prettier-eslint/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/prettier-eslint/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/prettier-eslint/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,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/prettier-eslint/node_modules/eslint": {
"version": "7.32.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
"integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"dependencies": {
"@babel/code-frame": "7.12.11",
@@ -12271,6 +12220,18 @@
"node": ">=4.0"
}
},
+ "node_modules/prettier-eslint/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/prettier-eslint/node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
@@ -12286,15 +12247,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/prettier-eslint/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/prettier-eslint/node_modules/ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -12356,18 +12308,6 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true
},
- "node_modules/prettier-eslint/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/prettier-eslint/node_modules/type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
@@ -12415,6 +12355,33 @@
"ansi-styles": "^3.2.0"
}
},
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pretty-format/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/pretty-format/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
"node_modules/proc-log": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
@@ -12592,27 +12559,16 @@
}
},
"node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/readdirp/node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz",
+ "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==",
"dev": true,
"engines": {
- "node": ">=8.6"
+ "node": ">= 14.18.0"
},
"funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
}
},
"node_modules/reflect-metadata": {
@@ -12673,15 +12629,15 @@
}
},
"node_modules/regexpu-core": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
- "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
+ "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
"dev": true,
"dependencies": {
- "@babel/regjsgen": "^0.8.0",
"regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.1.0",
- "regjsparser": "^0.9.1",
+ "regenerate-unicode-properties": "^10.2.0",
+ "regjsgen": "^0.8.0",
+ "regjsparser": "^0.12.0",
"unicode-match-property-ecmascript": "^2.0.0",
"unicode-match-property-value-ecmascript": "^2.1.0"
},
@@ -12689,25 +12645,34 @@
"node": ">=4"
}
},
+ "node_modules/regjsgen": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
+ "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+ "dev": true
+ },
"node_modules/regjsparser": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
- "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
"dev": true,
"dependencies": {
- "jsesc": "~0.5.0"
+ "jsesc": "~3.0.2"
},
"bin": {
"regjsparser": "bin/parser"
}
},
"node_modules/regjsparser/node_modules/jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"dev": true,
"bin": {
"jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/reinterval": {
@@ -12963,6 +12928,23 @@
}
]
},
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@@ -13026,6 +13008,66 @@
}
}
},
+ "node_modules/sass/node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/sass/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/sass/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/sass/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
"node_modules/sax": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
@@ -13034,9 +13076,9 @@
"optional": true
},
"node_modules/schema-utils": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
- "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
@@ -13045,7 +13087,7 @@
"ajv-keywords": "^5.1.0"
},
"engines": {
- "node": ">= 12.13.0"
+ "node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
@@ -13262,23 +13304,6 @@
"node": ">= 0.8"
}
},
- "node_modules/set-function-length": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
- "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
- "dev": true,
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -13319,24 +13344,81 @@
}
},
"node_modules/shell-quote": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
- "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
+ "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
"dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
- "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.7",
"es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.4",
- "object-inspect": "^1.13.1"
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "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"
@@ -13425,9 +13507,9 @@
}
},
"node_modules/socket.io": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz",
- "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==",
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
+ "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
"dev": true,
"dependencies": {
"accepts": "~1.3.4",
@@ -13452,6 +13534,23 @@
"ws": "~8.17.1"
}
},
+ "node_modules/socket.io-adapter/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/socket.io-adapter/node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
@@ -13486,6 +13585,40 @@
"node": ">=10.0.0"
}
},
+ "node_modules/socket.io-parser/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/socket.io/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/sockjs": {
"version": "0.3.24",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
@@ -13512,12 +13645,12 @@
}
},
"node_modules/socks-proxy-agent": {
- "version": "8.0.4",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz",
- "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==",
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
"dev": true,
"dependencies": {
- "agent-base": "^7.1.1",
+ "agent-base": "^7.1.2",
"debug": "^4.3.4",
"socks": "^2.8.3"
},
@@ -13621,9 +13754,9 @@
}
},
"node_modules/spdx-license-ids": {
- "version": "3.0.20",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz",
- "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==",
+ "version": "3.0.21",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz",
+ "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==",
"dev": true
},
"node_modules/spdy": {
@@ -13857,15 +13990,15 @@
}
},
"node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": {
- "has-flag": "^3.0.0"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/supports-preserve-symlinks-flag": {
@@ -13890,9 +14023,9 @@
}
},
"node_modules/synckit": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz",
- "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==",
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz",
+ "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==",
"dev": true,
"dependencies": {
"@pkgr/core": "^0.1.0",
@@ -13906,9 +14039,9 @@
}
},
"node_modules/table": {
- "version": "6.8.2",
- "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz",
- "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz",
+ "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
"dev": true,
"dependencies": {
"ajv": "^8.0.1",
@@ -13921,39 +14054,6 @@
"node": ">=10.0.0"
}
},
- "node_modules/table/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/table/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/table/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"node_modules/table/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -14096,16 +14196,16 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.10",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
- "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
+ "version": "5.3.11",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz",
+ "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==",
"dev": true,
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.20",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.1",
- "terser": "^5.26.0"
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
},
"engines": {
"node": ">= 10.13.0"
@@ -14129,55 +14229,6 @@
}
}
},
- "node_modules/terser-webpack-plugin/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "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"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "peerDependencies": {
- "ajv": "^6.9.1"
- }
- },
- "node_modules/terser-webpack-plugin/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==",
- "dev": true
- },
- "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
- "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
- "dev": true,
- "dependencies": {
- "@types/json-schema": "^7.0.8",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -14214,15 +14265,6 @@
"node": ">=0.6.0"
}
},
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -14270,21 +14312,21 @@
}
},
"node_modules/ts-api-utils": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
- "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz",
+ "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==",
"dev": true,
"engines": {
- "node": ">=16"
+ "node": ">=18.12"
},
"peerDependencies": {
- "typescript": ">=4.2.0"
+ "typescript": ">=4.8.4"
}
},
"node_modules/tslib": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
- "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
},
"node_modules/tsutils": {
"version": "3.21.0",
@@ -14383,9 +14425,9 @@
}
},
"node_modules/ua-parser-js": {
- "version": "0.7.39",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.39.tgz",
- "integrity": "sha512-IZ6acm6RhQHNibSt7+c09hhvsKy9WUr4DVbeq9U8o71qxyYtJpQeDxQnMrVqnIFMLcQjHO0I9wgfO2vIahht4w==",
+ "version": "0.7.40",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz",
+ "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==",
"dev": true,
"funding": [
{
@@ -14409,9 +14451,9 @@
}
},
"node_modules/undici-types": {
- "version": "6.19.8",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
- "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"dev": true
},
"node_modules/unicode-canonical-property-names-ecmascript": {
@@ -14509,9 +14551,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
- "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
+ "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
"dev": true,
"funding": [
{
@@ -14529,7 +14571,7 @@
],
"dependencies": {
"escalade": "^3.2.0",
- "picocolors": "^1.1.0"
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -14614,9 +14656,9 @@
}
},
"node_modules/vite": {
- "version": "5.4.6",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz",
- "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==",
+ "version": "5.4.14",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz",
+ "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==",
"dev": true,
"dependencies": {
"esbuild": "^0.21.3",
@@ -15079,9 +15121,9 @@
}
},
"node_modules/vite/node_modules/postcss": {
- "version": "8.4.47",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
- "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
+ "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
"dev": true,
"funding": [
{
@@ -15098,8 +15140,8 @@
}
],
"dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.1.0",
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
@@ -15366,6 +15408,30 @@
}
}
},
+ "node_modules/webpack-dev-server/node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
"node_modules/webpack-dev-server/node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
@@ -15386,10 +15452,22 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/webpack-dev-server/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/webpack-dev-server/node_modules/http-proxy-middleware": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz",
- "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==",
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
+ "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
"dev": true,
"dependencies": {
"@types/http-proxy": "^1.17.8",
@@ -15410,6 +15488,30 @@
}
}
},
+ "node_modules/webpack-dev-server/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
"node_modules/webpack-dev-server/node_modules/rimraf": {
"version": "5.0.10",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
@@ -15652,39 +15754,6 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
- "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -15714,39 +15783,6 @@
"node": ">=8"
}
},
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
"node_modules/wrap-ansi/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
diff --git a/modules/ui/src/app/app.store.spec.ts b/modules/ui/src/app/app.store.spec.ts
index 300a250fd..40b2d26dc 100644
--- a/modules/ui/src/app/app.store.spec.ts
+++ b/modules/ui/src/app/app.store.spec.ts
@@ -53,6 +53,7 @@ import { FocusManagerService } from './services/focus-manager.service';
import { TestRunMqttService } from './services/test-run-mqtt.service';
import { MOCK_ADAPTERS } from './mocks/settings.mock';
import { TestingType } from './model/device';
+import { ResultOfTestrun, StatusOfTestrun } from './model/testrun-status';
const mock = (() => {
let store: { [key: string]: string } = {};
@@ -499,7 +500,8 @@ describe('AppStore', () => {
store.overrideSelector(selectIsTestingComplete, true);
store.overrideSelector(selectSystemStatus, {
- status: 'Compliant',
+ result: ResultOfTestrun.Compliant,
+ status: StatusOfTestrun.Complete,
mac_addr: '00:1e:42:35:73:c4',
device: {
manufacturer: 'Delta',
diff --git a/modules/ui/src/app/app.store.ts b/modules/ui/src/app/app.store.ts
index a12a536a3..9b07fddf7 100644
--- a/modules/ui/src/app/app.store.ts
+++ b/modules/ui/src/app/app.store.ts
@@ -53,7 +53,7 @@ import {
setTestModules,
updateAdapters,
} from './store/actions';
-import { StatusOfTestrun, TestrunStatus } from './model/testrun-status';
+import { ResultOfTestrun, TestrunStatus } from './model/testrun-status';
import {
Adapters,
SettingMissedError,
@@ -333,7 +333,7 @@ export class AppStore extends ComponentStore {
filter(([isTestingComplete]) => isTestingComplete === true),
filter(
([, testrunStatus]) =>
- testrunStatus?.status === StatusOfTestrun.Compliant &&
+ testrunStatus?.result === ResultOfTestrun.Compliant &&
testrunStatus?.device.test_pack === TestingType.Pilot
),
tap(() => {
diff --git a/modules/ui/src/app/components/download-report/download-report.component.ts b/modules/ui/src/app/components/download-report/download-report.component.ts
index dcabc2281..8184ef6fc 100644
--- a/modules/ui/src/app/components/download-report/download-report.component.ts
+++ b/modules/ui/src/app/components/download-report/download-report.component.ts
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
-import { StatusOfTestrun, TestrunStatus } from '../../model/testrun-status';
+import { ResultOfTestrun, TestrunStatus } from '../../model/testrun-status';
import { CommonModule, DatePipe } from '@angular/common';
import { MatTooltipModule } from '@angular/material/tooltip';
import { ReportActionComponent } from '../report-action/report-action.component';
@@ -40,16 +40,16 @@ export class DownloadReportComponent extends ReportActionComponent {
}
return `${data.device.manufacturer} ${data.device.model} ${
data.device.firmware
- } ${data.status} ${this.getFormattedDateString(data.started)}`
+ } ${data.result ? data.result : data.status} ${this.getFormattedDateString(data.started)}`
.replace(/ /g, '_')
.toLowerCase();
}
getClass(data: TestrunStatus) {
- if (data.status === StatusOfTestrun.Compliant) {
+ if (data.result === ResultOfTestrun.Compliant) {
return `${this.class}-compliant`;
}
- if (data.status === StatusOfTestrun.NonCompliant) {
+ if (data.result === ResultOfTestrun.NonCompliant) {
return `${this.class}-non-compliant`;
}
return this.class;
diff --git a/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.html b/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.html
index f949fb279..61ba85614 100644
--- a/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.html
+++ b/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.html
@@ -17,9 +17,8 @@
{{ data.testrunStatus.device.manufacturer }}
- {{ data.testrunStatus.device.model }} v{{
- data.testrunStatus.device.firmware
- }}
+ {{ data.testrunStatus.device.model }}
+ {{ data.testrunStatus.device.firmware }}
{{ data.testrunStatus.device.test_pack }} testing has just finished
@@ -29,11 +28,15 @@
class="testing-result"
id="testing-result-main-info"
[class]="
- data.testrunStatus.status === StatusOfTestrun.Compliant
+ (data.testrunStatus.result === ResultOfTestrun.Compliant &&
+ data.testrunStatus.status === StatusOfTestrun.Complete) ||
+ data.testrunStatus.status === StatusOfTestrun.Proceed
? 'success-result'
: 'failed-result'
">
-
{{ data.testrunStatus.status }}
+
+ {{ getTestingResult(data.testrunStatus) }}
+
{{ data.testrunStatus.description }}
diff --git a/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.ts b/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.ts
index 199d89bf5..bb4c54b62 100644
--- a/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.ts
+++ b/modules/ui/src/app/components/download-zip-modal/download-zip-modal.component.ts
@@ -25,7 +25,11 @@ import { MatOptionModule } from '@angular/material/core';
import { TestRunService } from '../../services/test-run.service';
import { Routes } from '../../model/routes';
import { Router, RouterLink } from '@angular/router';
-import { TestrunStatus, StatusOfTestrun } from '../../model/testrun-status';
+import {
+ TestrunStatus,
+ StatusOfTestrun,
+ ResultOfTestrun,
+} from '../../model/testrun-status';
import { DownloadReportComponent } from '../download-report/download-report.component';
import { Subject, takeUntil, timer } from 'rxjs';
import { FocusManagerService } from '../../services/focus-manager.service';
@@ -80,6 +84,7 @@ export class DownloadZipModalComponent
} as Profile;
public readonly Routes = Routes;
public readonly StatusOfTestrun = StatusOfTestrun;
+ public readonly ResultOfTestrun = ResultOfTestrun;
profiles: Profile[] = [];
selectedProfile: Profile;
constructor(
@@ -165,6 +170,13 @@ export class DownloadZipModalComponent
return this.testRunService.getRiskClass(riskResult);
}
+ public getTestingResult(data: TestrunStatus): string {
+ if (data.status === StatusOfTestrun.Complete && data.result) {
+ return data.result;
+ }
+ return data.status;
+ }
+
private getZipLink(reportURL: string): string {
return reportURL.replace('report', 'export');
}
diff --git a/modules/ui/src/app/mocks/reports.mock.ts b/modules/ui/src/app/mocks/reports.mock.ts
index 2889b0571..0c127b18c 100644
--- a/modules/ui/src/app/mocks/reports.mock.ts
+++ b/modules/ui/src/app/mocks/reports.mock.ts
@@ -5,7 +5,8 @@ import { DeviceStatus, TestingType } from '../model/device';
export const HISTORY = [
{
mac_addr: '01:02:03:04:05:06',
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
device: {
status: DeviceStatus.VALID,
manufacturer: 'Delta',
@@ -20,7 +21,8 @@ export const HISTORY = [
finished: '2023-06-23T10:17:10.123Z',
},
{
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
mac_addr: '01:02:03:04:05:07',
device: {
status: DeviceStatus.VALID,
@@ -37,7 +39,8 @@ export const HISTORY = [
},
{
mac_addr: null,
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
device: {
status: DeviceStatus.VALID,
manufacturer: 'Delta',
@@ -56,7 +59,8 @@ export const HISTORY = [
export const HISTORY_AFTER_REMOVE = [
{
mac_addr: '01:02:03:04:05:06',
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
device: {
status: DeviceStatus.VALID,
manufacturer: 'Delta',
@@ -72,7 +76,8 @@ export const HISTORY_AFTER_REMOVE = [
},
{
mac_addr: null,
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
device: {
status: DeviceStatus.VALID,
manufacturer: 'Delta',
@@ -86,11 +91,12 @@ export const HISTORY_AFTER_REMOVE = [
started: '2023-06-23T10:11:00.123Z',
finished: '2023-06-23T10:17:10.123Z',
},
-];
+] as TestrunStatus[];
export const FORMATTED_HISTORY = [
{
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
mac_addr: '01:02:03:04:05:06',
device: {
status: DeviceStatus.VALID,
@@ -106,11 +112,13 @@ export const FORMATTED_HISTORY = [
finished: '2023-06-23T10:17:10.123Z',
deviceFirmware: '1.2.2',
deviceInfo: 'Delta 03-DIN-SRC',
+ testResult: 'Compliant',
duration: '06m 10s',
program: 'Device Qualification',
},
{
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
mac_addr: '01:02:03:04:05:07',
device: {
status: DeviceStatus.VALID,
@@ -126,12 +134,14 @@ export const FORMATTED_HISTORY = [
finished: '2023-07-23T10:17:10.123Z',
deviceFirmware: '1.2.3',
deviceInfo: 'Delta 03-DIN-SRC',
+ testResult: 'Compliant',
duration: '06m 10s',
program: 'Device Qualification',
},
{
mac_addr: null,
- status: 'compliant',
+ status: 'Complete',
+ result: 'Compliant',
device: {
status: DeviceStatus.VALID,
manufacturer: 'Delta',
@@ -146,10 +156,11 @@ export const FORMATTED_HISTORY = [
finished: '2023-06-23T10:17:10.123Z',
deviceFirmware: '1.2.2',
deviceInfo: 'Delta 03-DIN-SRC',
+ testResult: 'Compliant',
duration: '06m 10s',
program: 'Device Qualification',
},
-];
+] as HistoryTestrun[];
export const FILTERS = {
deviceInfo: 'test',
diff --git a/modules/ui/src/app/mocks/testrun.mock.ts b/modules/ui/src/app/mocks/testrun.mock.ts
index 3decf9973..48321f2d5 100644
--- a/modules/ui/src/app/mocks/testrun.mock.ts
+++ b/modules/ui/src/app/mocks/testrun.mock.ts
@@ -15,6 +15,8 @@
*/
import {
IResult,
+ RequiredResult,
+ ResultOfTestrun,
StatusOfTestrun,
TestrunStatus,
TestsData,
@@ -26,17 +28,20 @@ export const TEST_DATA_RESULT: IResult[] = [
name: 'dns.network.hostname_resolution',
description: 'The device should resolve hostnames',
result: 'Compliant',
+ required_result: RequiredResult.Required,
},
{
name: 'dns.network.from_dhcp',
description:
'The device should use the DNS server provided by the DHCP server',
result: 'Non-Compliant',
+ required_result: RequiredResult.Informational,
},
{
name: 'dns.mdns',
description: 'Does the device has MDNS (or any kind of IP multicast)',
result: 'Not Started',
+ required_result: RequiredResult.RequiredIfApplicable,
},
];
@@ -50,6 +55,7 @@ export const TEST_DATA_RESULT_WITH_RECOMMENDATIONS: IResult[] = [
'An example of a step to resolve',
'Disable any running NTP server',
],
+ required_result: RequiredResult.Required,
},
];
@@ -58,17 +64,20 @@ export const TEST_DATA_RESULT_WITH_ERROR: IResult[] = [
name: 'dns.network.hostname_resolution',
description: 'The device should resolve hostnames',
result: 'Compliant',
+ required_result: RequiredResult.Required,
},
{
name: 'dns.network.from_dhcp',
description:
'The device should use the DNS server provided by the DHCP server',
result: 'Error',
+ required_result: RequiredResult.Required,
},
{
name: 'dns.mdns',
description: 'Does the device has MDNS (or any kind of IP multicast)',
result: 'Not Started',
+ required_result: RequiredResult.Required,
},
];
@@ -87,12 +96,13 @@ export const TEST_DATA: TestsData = {
};
const PROGRESS_DATA_RESPONSE = (
- status: string,
+ status: StatusOfTestrun,
finished: string | null,
tests: TestsData | IResult[],
- report: string = ''
+ report: string = '',
+ result?: ResultOfTestrun
) => {
- return {
+ const response = {
status,
mac_addr: '01:02:03:04:05:06',
device: {
@@ -107,7 +117,11 @@ const PROGRESS_DATA_RESPONSE = (
tests,
report,
tags: ['VSA', 'Other tag', 'And one more'],
- };
+ } as TestrunStatus;
+ if (result) {
+ response.result = result;
+ }
+ return response;
};
export const MOCK_PROGRESS_DATA_CANCELLING: TestrunStatus =
@@ -118,18 +132,20 @@ export const MOCK_PROGRESS_DATA_IN_PROGRESS_EMPTY: TestrunStatus =
PROGRESS_DATA_RESPONSE(StatusOfTestrun.InProgress, null, []);
export const MOCK_PROGRESS_DATA_COMPLIANT: TestrunStatus =
PROGRESS_DATA_RESPONSE(
- StatusOfTestrun.Compliant,
+ StatusOfTestrun.Complete,
'2023-06-22T09:20:00.123Z',
TEST_DATA_RESULT,
- 'https://api.testrun.io/report.pdf'
+ 'https://api.testrun.io/report.pdf',
+ ResultOfTestrun.Compliant
);
export const MOCK_PROGRESS_DATA_NON_COMPLIANT: TestrunStatus =
PROGRESS_DATA_RESPONSE(
- StatusOfTestrun.NonCompliant,
+ StatusOfTestrun.Complete,
'2023-06-22T09:20:00.123Z',
TEST_DATA_RESULT,
- 'https://api.testrun.io/report.pdf'
+ 'https://api.testrun.io/report.pdf',
+ ResultOfTestrun.NonCompliant
);
export const MOCK_PROGRESS_DATA_CANCELLED: TestrunStatus =
@@ -159,6 +175,12 @@ export const MOCK_PROGRESS_DATA_WAITING_FOR_DEVICE: TestrunStatus = {
started: null,
};
+export const MOCK_PROGRESS_DATA_STARTING: TestrunStatus = {
+ ...MOCK_PROGRESS_DATA_IN_PROGRESS,
+ status: StatusOfTestrun.Starting,
+ started: null,
+};
+
export const MOCK_PROGRESS_DATA_VALIDATING: TestrunStatus = {
...MOCK_PROGRESS_DATA_IN_PROGRESS,
status: StatusOfTestrun.Validating,
diff --git a/modules/ui/src/app/model/testrun-status.ts b/modules/ui/src/app/model/testrun-status.ts
index f14dce652..04596d5e4 100644
--- a/modules/ui/src/app/model/testrun-status.ts
+++ b/modules/ui/src/app/model/testrun-status.ts
@@ -17,7 +17,8 @@ import { Device } from './device';
export interface TestrunStatus {
mac_addr: string | null;
- status: string;
+ status: StatusOfTestrun;
+ result?: ResultOfTestrun;
description?: string;
device: IDevice;
started: string | null;
@@ -30,6 +31,7 @@ export interface TestrunStatus {
export interface HistoryTestrun extends TestrunStatus {
deviceFirmware: string;
deviceInfo: string;
+ testResult: string;
program: string;
duration: string;
}
@@ -50,6 +52,18 @@ export interface IResult {
description: string;
result: string;
recommendations?: string[];
+ required_result: RequiredResult;
+}
+
+export enum RequiredResult {
+ Informational = 'Informational',
+ Required = 'Required',
+ RequiredIfApplicable = 'Required if Applicable',
+}
+
+export enum ResultOfTestrun {
+ Compliant = 'Compliant', // used for Completed
+ NonCompliant = 'Non-Compliant', // used for Completed
}
export enum StatusOfTestrun {
@@ -58,15 +72,17 @@ export enum StatusOfTestrun {
Cancelled = 'Cancelled',
Cancelling = 'Cancelling',
Failed = 'Failed',
- Compliant = 'Compliant', // used for Completed
CompliantLimited = 'Compliant (Limited)',
CompliantHigh = 'Compliant (High)',
- NonCompliant = 'Non-Compliant', // used for Completed
- SmartReady = 'Smart Ready', // used for Completed
+ SmartReady = 'Smart Ready',
Idle = 'Idle',
Monitoring = 'Monitoring',
+ Starting = 'Starting',
Error = 'Error',
Validating = 'Validating Network',
+ Complete = 'Complete', // device qualification
+ Proceed = 'Proceed', // pilot assessment
+ DoNotProceed = 'Do Not Proceed', // pilot assessment
}
export enum StatusOfTestResult {
diff --git a/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.scss b/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.scss
index c2088c67b..902986f90 100644
--- a/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.scss
+++ b/modules/ui/src/app/pages/devices/components/device-qualification-from/device-qualification-from.component.scss
@@ -22,7 +22,6 @@ $form-min-width: 732px;
:host {
container-type: size;
container-name: qualification-form;
-
display: grid;
grid-template-rows: 1fr;
overflow: auto;
diff --git a/modules/ui/src/app/pages/reports/components/filter-dialog/filter-dialog.component.ts b/modules/ui/src/app/pages/reports/components/filter-dialog/filter-dialog.component.ts
index 3d8ac231a..6dd78f401 100644
--- a/modules/ui/src/app/pages/reports/components/filter-dialog/filter-dialog.component.ts
+++ b/modules/ui/src/app/pages/reports/components/filter-dialog/filter-dialog.component.ts
@@ -58,7 +58,10 @@ import {
DateRange as LocalDateRange,
} from '../../../../model/filters';
import { EscapableDialogComponent } from '../../../../components/escapable-dialog/escapable-dialog.component';
-import { StatusOfTestResult } from '../../../../model/testrun-status';
+import {
+ ResultOfTestrun,
+ StatusOfTestrun,
+} from '../../../../model/testrun-status';
import { DeviceValidators } from '../../../devices/components/device-form/device.validators';
interface DialogData {
@@ -97,8 +100,10 @@ export class FilterDialogComponent
implements OnInit
{
resultList = [
- { value: StatusOfTestResult.Compliant, enabled: false },
- { value: StatusOfTestResult.NonCompliant, enabled: false },
+ { value: ResultOfTestrun.Compliant, enabled: false },
+ { value: ResultOfTestrun.NonCompliant, enabled: false },
+ { value: StatusOfTestrun.Proceed, enabled: false },
+ { value: StatusOfTestrun.DoNotProceed, enabled: false },
];
filterForm!: FormGroup;
selectedRangeValue!: DateRange
| undefined;
diff --git a/modules/ui/src/app/pages/reports/reports.component.html b/modules/ui/src/app/pages/reports/reports.component.html
index beb538149..c187a6c27 100644
--- a/modules/ui/src/app/pages/reports/reports.component.html
+++ b/modules/ui/src/app/pages/reports/reports.component.html
@@ -147,9 +147,9 @@ Reports
- {{ data.status }}
+ {{ data.testResult }}
diff --git a/modules/ui/src/app/pages/reports/reports.store.ts b/modules/ui/src/app/pages/reports/reports.store.ts
index 7b13bf5e9..de0bf20c3 100644
--- a/modules/ui/src/app/pages/reports/reports.store.ts
+++ b/modules/ui/src/app/pages/reports/reports.store.ts
@@ -12,6 +12,7 @@ import { selectReports, selectRiskProfiles } from '../../store/selectors';
import { Store } from '@ngrx/store';
import { AppState } from '../../store/state';
import { fetchReports, setReports } from '../../store/actions';
+import { TestingType } from '../../model/device';
export interface ReportsComponentState {
displayedColumns: string[];
@@ -252,12 +253,24 @@ export class ReportsStore extends ComponentStore {
...item,
deviceFirmware: item.device.firmware,
deviceInfo: item.device.manufacturer + ' ' + item.device.model,
+ testResult: this.getTestResult(item),
duration: this.getDuration(item.started, item.finished),
program: item.device.test_pack ?? '',
};
});
}
+ private getTestResult(item: TestrunStatus): string {
+ let result = '';
+ if (item.device.test_pack === TestingType.Qualification) {
+ result = item.result ? item.result : item.status;
+ }
+ if (item.device.test_pack === TestingType.Pilot) {
+ result = item.status;
+ }
+ return result;
+ }
+
private getDuration(started: string | null, finished: string | null): string {
if (!started || !finished) {
return '';
@@ -290,7 +303,7 @@ export class ReportsStore extends ComponentStore {
const isIncludeStatus =
searchString.results?.length === 0 ||
- searchString.results?.includes(data.status);
+ searchString.results?.includes(data.testResult);
const isIncludeStartedDate = this.filterStartedDateRange(
data.started,
searchString
diff --git a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts
index d279a1f14..12ae7457e 100644
--- a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts
+++ b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.spec.ts
@@ -89,6 +89,9 @@ describe('ProfileFormComponent', () => {
[
'very long value very long value very long value very long value very long value very long value very long value',
'as&@3$',
+ 'test/',
+ 'test[',
+ ':test',
].forEach(value => {
const name: HTMLInputElement = compiled.querySelector(
'.form-name'
diff --git a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts
index 2656221cd..cc6a18e8d 100644
--- a/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts
+++ b/modules/ui/src/app/pages/risk-assessment/profile-form/profile-form.component.ts
@@ -156,7 +156,7 @@ export class ProfileFormComponent implements OnInit, AfterViewInit {
group['name'] = new FormControl('', [
this.profileValidators.textRequired(),
- this.deviceValidators.deviceStringFormat(),
+ this.profileValidators.profileNameFormat(),
this.nameValidator,
]);
diff --git a/modules/ui/src/app/pages/risk-assessment/profile-form/profile.validators.ts b/modules/ui/src/app/pages/risk-assessment/profile-form/profile.validators.ts
index 10280586d..d3847345d 100644
--- a/modules/ui/src/app/pages/risk-assessment/profile-form/profile.validators.ts
+++ b/modules/ui/src/app/pages/risk-assessment/profile-form/profile.validators.ts
@@ -31,6 +31,12 @@ export class ProfileValidators {
readonly STRING_FORMAT_REGEXP = new RegExp('^[^"\\\\]*$', 'u');
+ // Not allowed symbols: <>?/:;@'"][=^!\#$%&*+{}|()
+ readonly PROFILE_NAME_FORMAT_REGEXP = new RegExp(
+ '^([^<>?:;@\'\\\\"\\[\\]=^!/,.#$%&*+{}|()]{1,28})$',
+ 'u'
+ );
+
public differentProfileName(
profiles: Profile[],
profile: Profile | null
@@ -60,6 +66,10 @@ export class ProfileValidators {
};
}
+ public profileNameFormat(): ValidatorFn {
+ return this.stringFormat(this.PROFILE_NAME_FORMAT_REGEXP);
+ }
+
public multiSelectRequired(g: FormGroup) {
if (Object.values(g.value).every(value => value === false)) {
return { required: true };
diff --git a/modules/ui/src/app/pages/testrun/components/download-options/download-options.component.ts b/modules/ui/src/app/pages/testrun/components/download-options/download-options.component.ts
index 81b4a1fee..814584eb0 100644
--- a/modules/ui/src/app/pages/testrun/components/download-options/download-options.component.ts
+++ b/modules/ui/src/app/pages/testrun/components/download-options/download-options.component.ts
@@ -26,7 +26,7 @@ import { MatSelectModule } from '@angular/material/select';
import { CommonModule, DatePipe } from '@angular/common';
import { MatIconModule } from '@angular/material/icon';
import {
- StatusOfTestrun,
+ ResultOfTestrun,
TestrunStatus,
} from '../../../../model/testrun-status';
import { MatOptionSelectionChange } from '@angular/material/core';
@@ -113,9 +113,9 @@ export class DownloadOptionsComponent {
sendGAEvent(data: TestrunStatus, type: string) {
let event = `download_report_${type === DownloadOption.PDF ? 'pdf' : 'zip'}`;
- if (data.status === StatusOfTestrun.Compliant) {
+ if (data.result === ResultOfTestrun.Compliant) {
event += '_compliant';
- } else if (data.status === StatusOfTestrun.NonCompliant) {
+ } else if (data.result === ResultOfTestrun.NonCompliant) {
event += '_non_compliant';
}
// @ts-expect-error data layer is not null
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-initiate-form/testrun-initiate-form.component.ts b/modules/ui/src/app/pages/testrun/components/testrun-initiate-form/testrun-initiate-form.component.ts
index cbec35a0a..0fddce670 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-initiate-form/testrun-initiate-form.component.ts
+++ b/modules/ui/src/app/pages/testrun/components/testrun-initiate-form/testrun-initiate-form.component.ts
@@ -59,6 +59,7 @@ export class TestrunInitiateFormComponent
extends EscapableDialogComponent
implements OnInit, AfterViewChecked
{
+ private startRequestSent = new BehaviorSubject(false);
@ViewChild('firmwareInput') firmwareInput!: ElementRef;
initiateForm!: FormGroup;
devices$ = this.store.select(selectDevices);
@@ -165,7 +166,8 @@ export class TestrunInitiateFormComponent
}
);
- if (this.selectedDevice) {
+ if (this.selectedDevice && !this.startRequestSent.value) {
+ this.startRequestSent.next(true);
this.testRunService.fetchVersion();
this.testRunService
.startTestrun({
@@ -174,8 +176,13 @@ export class TestrunInitiateFormComponent
test_modules: testModules,
})
.pipe(take(1))
- .subscribe(status => {
- this.cancel(status);
+ .subscribe({
+ next: status => {
+ this.cancel(status);
+ },
+ error: () => {
+ this.startRequestSent.next(false);
+ },
});
}
}
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html
index 9ca1d80b2..ca8009264 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html
+++ b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.html
@@ -16,7 +16,8 @@
@@ -126,6 +127,16 @@
Test result
+
+ {{ getTestResult(data) }}
+
+
+
+
Preliminary Pilot Recommendation
{{ data.status }}
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.scss b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.scss
index b7c86a91a..8cd685de0 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.scss
+++ b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.scss
@@ -32,6 +32,10 @@
box-sizing: border-box;
padding: 16px 32px;
+ &-pilot {
+ gap: 6px;
+ }
+
&.progress {
background-color: mat.m2-get-color-from-palette($color-primary, 700);
}
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.spec.ts b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.spec.ts
index 2e35d0581..1bad5681f 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.spec.ts
+++ b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.spec.ts
@@ -17,6 +17,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TestrunStatusCardComponent } from './testrun-status-card.component';
import {
+ ResultOfTestrun,
StatusOfTestrun,
TestrunStatus,
} from '../../../../model/testrun-status';
@@ -62,14 +63,16 @@ describe('ProgressStatusCardComponent', () => {
];
const statusesForCompletedSuccessClass = [
- StatusOfTestrun.Compliant,
+ StatusOfTestrun.Complete,
StatusOfTestrun.CompliantLimited,
StatusOfTestrun.CompliantHigh,
+ StatusOfTestrun.Proceed,
];
const statusesForCompletedFailedClass = [
- StatusOfTestrun.NonCompliant,
+ StatusOfTestrun.Complete,
StatusOfTestrun.Error,
+ StatusOfTestrun.DoNotProceed,
];
statusesForProgressClass.forEach(testCase => {
@@ -89,7 +92,10 @@ describe('ProgressStatusCardComponent', () => {
'completed-success': true,
};
- const result = component.getClass(testCase);
+ const result = component.getClass(
+ testCase,
+ ResultOfTestrun.Compliant
+ );
expect(result).toEqual(expectedResult);
});
@@ -102,7 +108,10 @@ describe('ProgressStatusCardComponent', () => {
'completed-failed': true,
};
- const result = component.getClass(testCase);
+ const result = component.getClass(
+ testCase,
+ ResultOfTestrun.NonCompliant
+ );
expect(result).toEqual(expectedResult);
});
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts
index 101591c98..c41c502bb 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts
+++ b/modules/ui/src/app/pages/testrun/components/testrun-status-card/testrun-status-card.component.ts
@@ -16,11 +16,13 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import {
IResult,
+ ResultOfTestrun,
StatusOfTestResult,
StatusOfTestrun,
TestrunStatus,
TestsData,
} from '../../../../model/testrun-status';
+import { TestingType } from '../../../../model/device';
@Component({
selector: 'app-testrun-status-card',
@@ -32,8 +34,12 @@ export class TestrunStatusCardComponent {
@Input() systemStatus!: TestrunStatus;
public readonly StatusOfTestrun = StatusOfTestrun;
+ public readonly TestingType = TestingType;
- public getClass(status: string): {
+ public getClass(
+ status: StatusOfTestrun,
+ result?: ResultOfTestrun
+ ): {
progress: boolean;
'completed-success': boolean;
'completed-failed': boolean;
@@ -42,13 +48,17 @@ export class TestrunStatusCardComponent {
return {
progress: this.isProgressStatus(status),
'completed-success':
- status === StatusOfTestrun.Compliant ||
+ (result === ResultOfTestrun.Compliant &&
+ status === StatusOfTestrun.Complete) ||
status === StatusOfTestrun.CompliantLimited ||
status === StatusOfTestrun.CompliantHigh ||
- status === StatusOfTestrun.SmartReady,
+ status === StatusOfTestrun.SmartReady ||
+ status === StatusOfTestrun.Proceed,
'completed-failed':
- status === StatusOfTestrun.NonCompliant ||
- status === StatusOfTestrun.Error,
+ (result === ResultOfTestrun.NonCompliant &&
+ status === StatusOfTestrun.Complete) ||
+ status === StatusOfTestrun.Error ||
+ status === StatusOfTestrun.DoNotProceed,
canceled:
status === StatusOfTestrun.Cancelled ||
status === StatusOfTestrun.Cancelling,
@@ -88,11 +98,23 @@ export class TestrunStatusCardComponent {
}
}
+ public getTestResult(data: TestrunStatus): string {
+ if (
+ data.status === StatusOfTestrun.Complete ||
+ data.status === StatusOfTestrun.Proceed ||
+ data.status === StatusOfTestrun.DoNotProceed
+ ) {
+ return data.result!;
+ }
+ return data.status;
+ }
+
private isProgressStatus(status: string): boolean {
return (
status === StatusOfTestrun.Monitoring ||
status === StatusOfTestrun.InProgress ||
status === StatusOfTestrun.WaitingForDevice ||
+ status === StatusOfTestrun.Starting ||
status === StatusOfTestrun.Validating
);
}
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.html b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.html
index a94d48004..52105603e 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.html
+++ b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.html
@@ -19,6 +19,7 @@
+
{{ item.result }}
+
+
+
+ {{ item.required_result }}
+
+
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.scss b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.scss
index cc5bc118b..593eb06f0 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.scss
+++ b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.scss
@@ -88,17 +88,17 @@ $expander-button-size: 28px;
.tests-item-row {
min-height: $row-height;
height: auto;
- grid-template-columns: 1fr 2.2fr 160px 20px;
+ grid-template-columns: 1fr 2.2fr 150px 226px 20px;
border-bottom: 1px solid $lighter-grey;
}
.tests-header-row {
- grid-template-columns: 1fr 2.2fr 150px $expander-button-size;
+ grid-template-columns: 1fr 2.2fr 150px 220px $expander-button-size;
}
.expansion-panel-header ::ng-deep.mat-content {
display: grid;
- grid-template-columns: 1fr 2.2fr 154px;
+ grid-template-columns: 1fr 2.2fr 150px 220px;
}
.expansion-panel-header ::ng-deep .mat-expansion-indicator {
@@ -129,8 +129,8 @@ $expander-button-size: 28px;
.expansion-panel-row ::ng-deep.mat-expansion-panel-body {
display: grid;
- grid-template-columns: 1fr 2.2fr 160px 20px;
- grid-template-areas: '. description . .';
+ grid-template-columns: 1fr 2.2fr 150px 220px 20px;
+ grid-template-areas: '. description . . .';
}
.cel-description {
@@ -190,3 +190,80 @@ $expander-button-size: 28px;
border-radius: 0;
box-shadow: none;
}
+
+.tests-item-cell-required-result {
+ display: flex;
+ align-items: center;
+ .cell-result-required-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 14px;
+ height: 14px;
+ border-radius: 20px;
+ font-size: 12px;
+ &::before {
+ font-family: 'Material Symbols Outlined';
+ line-height: 14px;
+ }
+ }
+ &.roadmap {
+ color: #00639b;
+ .cell-result-required-icon {
+ background: #00639b;
+ color: #e1e3e1;
+ &::before {
+ content: 'road';
+ }
+ }
+ }
+ &.recommended {
+ color: #146c2e;
+ .cell-result-required-icon {
+ background: #146c2e;
+ color: #ffffff;
+ &::before {
+ font-variation-settings:
+ 'FILL' 1,
+ 'wght' 400,
+ 'GRAD' 0,
+ 'opsz' 24;
+ content: 'thumb_up';
+ font-size: 9px;
+ }
+ }
+ }
+ &.informational {
+ color: #146c2e;
+ .cell-result-required-icon {
+ background: #146c2e;
+ color: #ffffff;
+ &::before {
+ content: 'info_i';
+ }
+ }
+ }
+ &.required {
+ color: #1f1f1f;
+ .cell-result-required-icon {
+ background: #1f1f1f;
+ color: #e1e3e1;
+ &::before {
+ content: 'asterisk';
+ }
+ }
+ }
+ &.required-if-applicable {
+ color: #00639b;
+ .cell-result-required-icon {
+ background: #00639b;
+ color: #e1e3e1;
+ &::before {
+ content: 'asterisk';
+ }
+ }
+ }
+ .cell-result-required-text {
+ padding-left: 8px;
+ }
+}
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.spec.ts b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.spec.ts
index 73b7196e8..9f51d3d66 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.spec.ts
+++ b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.spec.ts
@@ -17,7 +17,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TestrunTableComponent } from './testrun-table.component';
-import { IResult, StatusOfTestResult } from '../../../../model/testrun-status';
+import {
+ IResult,
+ RequiredResult,
+ StatusOfTestResult,
+} from '../../../../model/testrun-status';
import {
TEST_DATA,
TEST_DATA_RESULT,
@@ -82,6 +86,20 @@ describe('ProgressTableComponent', () => {
expect(result).toEqual('Expand all rows');
});
+
+ it('#getRequiredResultClass should return class', () => {
+ const result1 = component.getRequiredResultClass(
+ RequiredResult.Informational
+ );
+ const result2 = component.getRequiredResultClass(
+ RequiredResult.RequiredIfApplicable
+ );
+ const result3 = component.getRequiredResultClass(RequiredResult.Required);
+
+ expect(result1).toEqual('informational');
+ expect(result2).toEqual('required-if-applicable');
+ expect(result3).toEqual('required');
+ });
});
describe('DOM tests', () => {
diff --git a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.ts b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.ts
index 40532dc29..586a01164 100644
--- a/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.ts
+++ b/modules/ui/src/app/pages/testrun/components/testrun-table/testrun-table.component.ts
@@ -53,6 +53,14 @@ export class TestrunTableComponent {
public getResultClass(result: string): StatusResultClassName {
return this.testRunService.getResultClass(result);
}
+
+ public getRequiredResultClass(result: string): string {
+ if (!result) {
+ return '';
+ }
+ return result.split(' ').join('-').toLowerCase();
+ }
+
public getAriaLabel(): string {
const action = this.isAllCollapsed ? 'Expand' : 'Collapse';
const message = this.stepsToResolveCount === 1 ? 'row' : 'all rows';
diff --git a/modules/ui/src/app/pages/testrun/testrun.store.spec.ts b/modules/ui/src/app/pages/testrun/testrun.store.spec.ts
index 24ffc6ba2..5518feb49 100644
--- a/modules/ui/src/app/pages/testrun/testrun.store.spec.ts
+++ b/modules/ui/src/app/pages/testrun/testrun.store.spec.ts
@@ -46,6 +46,7 @@ import {
MOCK_PROGRESS_DATA_VALIDATING,
TEST_DATA_RESULT_WITH_RECOMMENDATIONS,
TEST_DATA_TABLE_RESULT,
+ MOCK_PROGRESS_DATA_STARTING,
} from '../../mocks/testrun.mock';
import { LoaderService } from '../../services/loader.service';
@@ -187,6 +188,21 @@ describe('TestrunStore', () => {
});
});
+ it('should set value with empty values for status "Starting"', done => {
+ const expectedResult = EMPTY_RESULT;
+
+ store.overrideSelector(
+ selectSystemStatus,
+ MOCK_PROGRESS_DATA_STARTING
+ );
+ store.refreshState();
+
+ testrunStore.viewModel$.pipe(take(1)).subscribe(store => {
+ expect(store.dataSource).toEqual(expectedResult);
+ done();
+ });
+ });
+
it('should set value with empty values for status "Cancelled" and empty result', done => {
const expectedResult = EMPTY_RESULT;
diff --git a/modules/ui/src/app/pages/testrun/testrun.store.ts b/modules/ui/src/app/pages/testrun/testrun.store.ts
index 351ec10d1..b21ad4785 100644
--- a/modules/ui/src/app/pages/testrun/testrun.store.ts
+++ b/modules/ui/src/app/pages/testrun/testrun.store.ts
@@ -101,6 +101,7 @@ export class TestrunStore extends ComponentStore
{
if (
res?.status === StatusOfTestrun.Validating ||
res?.status === StatusOfTestrun.WaitingForDevice ||
+ res?.status === StatusOfTestrun.Starting ||
res?.status === StatusOfTestrun.Monitoring ||
(res?.status === StatusOfTestrun.InProgress &&
this.resultIsEmpty(res.tests))
@@ -123,6 +124,7 @@ export class TestrunStore extends ComponentStore {
res?.status === StatusOfTestrun.Validating ||
res?.status === StatusOfTestrun.Monitoring ||
res?.status === StatusOfTestrun.WaitingForDevice ||
+ res?.status === StatusOfTestrun.Starting ||
(res?.status === StatusOfTestrun.Cancelled && !results.length)
) {
this.setDataSource(EMPTY_RESULT);
@@ -210,6 +212,7 @@ export class TestrunStore extends ComponentStore {
return (
status === StatusOfTestrun.InProgress ||
status === StatusOfTestrun.WaitingForDevice ||
+ status === StatusOfTestrun.Starting ||
status === StatusOfTestrun.Monitoring ||
status === StatusOfTestrun.Validating
);
diff --git a/modules/ui/src/app/services/test-run.service.spec.ts b/modules/ui/src/app/services/test-run.service.spec.ts
index d50a9e8fc..b0c0ff7e0 100644
--- a/modules/ui/src/app/services/test-run.service.spec.ts
+++ b/modules/ui/src/app/services/test-run.service.spec.ts
@@ -228,7 +228,7 @@ describe('TestRunService', () => {
const reports = [
{
- status: 'Completed',
+ status: 'Complete',
device: device,
report: 'https://api.testrun.io/report.pdf',
started: '2023-06-22T10:11:00.123Z',
@@ -263,6 +263,7 @@ describe('TestRunService', () => {
const statusesForGreenRes = [
StatusOfTestResult.Compliant,
+ StatusOfTestrun.Proceed,
StatusOfTestResult.CompliantLimited,
StatusOfTestResult.CompliantHigh,
];
@@ -276,6 +277,7 @@ describe('TestRunService', () => {
const statusesForRedRes = [
StatusOfTestResult.NonCompliant,
+ StatusOfTestrun.DoNotProceed,
StatusOfTestResult.Error,
];
@@ -365,6 +367,7 @@ describe('TestRunService', () => {
const resultsInProgress = [
StatusOfTestrun.InProgress,
StatusOfTestrun.WaitingForDevice,
+ StatusOfTestrun.Starting,
StatusOfTestrun.Monitoring,
StatusOfTestrun.Validating,
];
@@ -372,8 +375,7 @@ describe('TestRunService', () => {
const resultsNotInProgress = [
StatusOfTestrun.Idle,
StatusOfTestrun.Cancelled,
- StatusOfTestrun.Compliant,
- StatusOfTestrun.NonCompliant,
+ StatusOfTestrun.Complete,
];
resultsInProgress.forEach(testCase => {
diff --git a/modules/ui/src/app/services/test-run.service.ts b/modules/ui/src/app/services/test-run.service.ts
index d7539d2ab..ee5b99f7c 100644
--- a/modules/ui/src/app/services/test-run.service.ts
+++ b/modules/ui/src/app/services/test-run.service.ts
@@ -164,10 +164,12 @@ export class TestRunService {
return {
green:
result === StatusOfTestResult.Compliant ||
+ result === StatusOfTestrun.Proceed ||
result === StatusOfTestResult.CompliantLimited ||
result === StatusOfTestResult.CompliantHigh,
red:
result === StatusOfTestResult.NonCompliant ||
+ result === StatusOfTestrun.DoNotProceed ||
result === StatusOfTestResult.Error,
blue:
result === StatusOfTestResult.SmartReady ||
@@ -192,6 +194,7 @@ export class TestRunService {
return (
status === StatusOfTestrun.InProgress ||
status === StatusOfTestrun.WaitingForDevice ||
+ status === StatusOfTestrun.Starting ||
status === StatusOfTestrun.Monitoring ||
status === StatusOfTestrun.Validating
);
diff --git a/modules/ui/src/app/store/effects.ts b/modules/ui/src/app/store/effects.ts
index 12140eb65..d248fb9e2 100644
--- a/modules/ui/src/app/store/effects.ts
+++ b/modules/ui/src/app/store/effects.ts
@@ -289,8 +289,9 @@ export class AppEffects {
private isTestrunFinished(status: string) {
return (
- status === StatusOfTestrun.Compliant ||
- status === StatusOfTestrun.NonCompliant ||
+ status === StatusOfTestrun.Complete ||
+ status === StatusOfTestrun.Proceed ||
+ status === StatusOfTestrun.DoNotProceed ||
status === StatusOfTestrun.Error
);
}
diff --git a/modules/ui/src/index.html b/modules/ui/src/index.html
index 1c79ceb31..7d747928d 100644
--- a/modules/ui/src/index.html
+++ b/modules/ui/src/index.html
@@ -75,8 +75,8 @@
href="https://fonts.googleapis.com/icon?family=Material+Icons|Material+Icons+Outlined"
rel="stylesheet" />
+ rel="stylesheet"
+ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
diff --git a/resources/report/module_report_base.jinja2 b/resources/report/module_report_base.jinja2
new file mode 100644
index 000000000..6e159c264
--- /dev/null
+++ b/resources/report/module_report_base.jinja2
@@ -0,0 +1,54 @@
+{% raw %}
+
+
+{% endraw %}
+
+ {% if module_header %}
+
{{ module_header }}
+ {% if summary_headers %}
+
+ {% endif %}
+ {% elif summary_headers %}
+
+ {% endif %}
+ {% if summary_headers %}
+
+
+ {% for header in summary_headers %}
+ {{ header }}
+ {% endfor %}
+
+
+
+
+ {% for cell in summary_data %}
+ {{ cell }}
+ {% endfor %}
+
+
+
+ {% endif %}
+ {% block content %}{% endblock content %}
+
+{% raw %}
+
+
+
+{% endraw %}
\ No newline at end of file
diff --git a/resources/report/test_report_styles.css b/resources/report/test_report_styles.css
index b1ed9d33c..90d7cb3d8 100644
--- a/resources/report/test_report_styles.css
+++ b/resources/report/test_report_styles.css
@@ -24,6 +24,13 @@
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
+ @font-face {
+ font-family: 'Material Symbols Outlined';
+ font-style: normal;
+ font-weight: 100 700;
+ src: url(https://fonts.gstatic.com/icon/font?kit=kJEhBvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oFsKTDIwram_2pN8sass6hd4ObOPvrgWc3Hc02BrFizbd_1DP&skey=b8dc2088854b122f&v=v225) format('woff2');
+ }
+
/* Define some common body formatting*/
body {
font-family: 'Google Sans', sans-serif;
@@ -222,6 +229,24 @@
word-break: break-word;
}
+ .module-data.dns-module thead tr th,
+ .module-data.dns-module tbody tr td {
+ padding: 12px 16px;
+ }
+
+ .module-data.dns-module tbody tr td {
+ max-width: 1px;
+ }
+
+ .module-data.dns-module tbody tr td.count-row {
+ width: 1px;
+ }
+
+ .module-data.dns-module tbody tr td div {
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ }
+
div.steps-to-resolve {
background-color: #F8F9FA;
margin-bottom: 30px;
@@ -415,6 +440,10 @@
border-top: 0;
}
+ .result-line-result-non-compliant-required {
+ background: #FCE8E6;
+ }
+
.result-list-header-label {
position: absolute;
font-size: 12px;
@@ -428,7 +457,7 @@
position: absolute;
font-size: 12px;
margin-top: 12px;
- max-width: 300px;
+ max-width: 185px;
font-weight: normal;
align-items: center;
text-overflow: ellipsis;
@@ -437,7 +466,7 @@
}
.result-test-description {
- max-width: 380px;
+ max-width: 300px;
}
.result-test-result-error {
@@ -467,7 +496,7 @@
margin-top: 8px;
padding: 4px 4px 7px 5px;
border-radius: 2px;
- left: 6.85in;
+ left: 5.4in;
}
.result-test-result-compliant {
@@ -480,6 +509,83 @@
color: #393939;
}
+ .material-symbols-outlined {
+ font-family: 'Material Symbols Outlined';
+ font-weight: normal;
+ font-style: normal;
+ line-height: 1;
+ letter-spacing: normal;
+ text-transform: none;
+ white-space: nowrap;
+ word-wrap: normal;
+ direction: ltr;
+ text-align: center;
+ font-size: 12px;
+ display: inline-flex;
+ width: 14px;
+ height: 14px;
+ line-height: 14px;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ flex-shrink: 0;
+ border-radius: 100%;
+ -webkit-font-feature-settings: 'liga';
+ -webkit-font-smoothing: antialiased;
+ vertical-align: bottom;
+ }
+
+ .result-test-required-result {
+ display: flex;
+ align-items: center;
+ overflow: visible;
+ }
+
+ .result-test-required-result-text {
+ line-height: 14px;
+ flex: 0 0 120px;
+ padding-left: 8px;
+ }
+
+ .result-test-required-result-informational, .result-test-required-result-recommended {
+ color: #0D652D;
+ }
+
+ .result-test-required-result-informational .material-symbols-outlined,
+ .result-test-required-result-recommended .material-symbols-outlined {
+ background: #0D652D;
+ color: #ffffff;
+ }
+
+ .result-test-required-result-recommended .material-symbols-outlined {
+ font-variation-settings:
+ 'FILL' 1,
+ 'wght' 400,
+ 'GRAD' 0,
+ 'opsz' 24;
+ font-size: 9px;
+ }
+
+ .result-test-required-result-required {
+ color: #000000;
+ }
+
+ .result-test-required-result-required .material-symbols-outlined {
+ background: #000000;
+ color: #ffffff;
+ }
+
+ .result-test-required-result-required-if-applicable,
+ .result-test-required-result-roadmap {
+ color: #174EA6;
+ }
+
+ .result-test-required-result-required-if-applicable .material-symbols-outlined,
+ .result-test-required-result-roadmap .material-symbols-outlined {
+ background: #174EA6;
+ color: #ffffff;
+ }
+
/* CSS for the footer */
.footer {
position: absolute;
@@ -639,4 +745,4 @@
width: 8.5in;
height: 11in;
}
- }
\ No newline at end of file
+ }
diff --git a/resources/test_packs/pilot.json b/resources/test_packs/pilot/config.json
similarity index 58%
rename from resources/test_packs/pilot.json
rename to resources/test_packs/pilot/config.json
index 587d0a25a..c7c1c47c6 100644
--- a/resources/test_packs/pilot.json
+++ b/resources/test_packs/pilot/config.json
@@ -1,29 +1,29 @@
{
"name": "Pilot Assessment",
"language": {
- "compliant_description": "Your device has met the initial pilot assessment requirements. Please send your Testrun ZIP file to the qualification lab for verification. The lab will then contact you with further instructions.",
- "non_compliant_description": "Your device didn't quite meet the initial pilot assessment requirements. The Testrun report will provide guidance on how to resolve any issues. If you require further support, please get in touch with the qualification lab."
+ "compliant_description": "This is a preliminary test result. Please attach the Risk Profile and download the test results. A full evaluation and recommendation will be provided by the lab team.",
+ "non_compliant_description": "This is a preliminary test result. Please attach the Risk Profile and download the test results. A full evaluation and recommendation will be provided by the lab team."
},
"tests": [
{
"name": "connection.port_link",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.port_speed",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.port_duplex",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.switch.arp_inspection",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.switch.dhcp_snooping",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.dhcp_address",
@@ -35,43 +35,51 @@
},
{
"name": "connection.mac_oui",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.private_address",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.shared_address",
- "required_result": "Informational"
+ "required_result": "Required"
+ },
+ {
+ "name": "connection.dhcp_disconnect",
+ "required_result": "Required"
+ },
+ {
+ "name": "connection.dhcp_disconnect_ip_change",
+ "required_result": "Required"
},
{
"name": "connection.single_ip",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.target_ping",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.ipaddr.ip_change",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.ipaddr.dhcp_failover",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.ipv6_slaac",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "connection.ipv6_ping",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "dns.network.hostname_resolution",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "dns.network.from_dhcp",
@@ -83,66 +91,70 @@
},
{
"name": "ntp.network.ntp_support",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "ntp.network.ntp_dhcp",
- "required_result": "Informational"
+ "required_result": "Roadmap"
},
{
"name": "protocol.valid_bacnet",
- "required_result": "Informational"
+ "required_result": "Recommended"
},
{
"name": "protocol.bacnet.version",
- "required_result": "Informational"
+ "required_result": "Recommended"
},
{
"name": "protocol.valid_modbus",
- "required_result": "Informational"
+ "required_result": "Recommended"
},
{
"name": "security.services.ftp",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.ssh.version",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.telnet",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.smtp",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.http",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.pop",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.imap",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.snmpv3",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.vnc",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "security.services.tftp",
- "required_result": "Informational"
+ "required_result": "Required"
},
{
"name": "ntp.network.ntp_server",
+ "required_result": "Required"
+ },
+ {
+ "name": "protocol.services.bacnet",
"required_result": "Informational"
},
{
@@ -151,11 +163,11 @@
},
{
"name": "security.tls.v1_2_server",
- "required_result": "Informational"
+ "required_result": "Required if Applicable"
},
{
"name": "security.tls.v1_2_client",
- "required_result": "Informational"
+ "required_result": "Required if Applicable"
},
{
"name": "security.tls.v1_3_server",
diff --git a/resources/test_packs/pilot/report_templates/device_profile.jinja b/resources/test_packs/pilot/report_templates/device_profile.jinja
new file mode 100644
index 000000000..8fb03c063
--- /dev/null
+++ b/resources/test_packs/pilot/report_templates/device_profile.jinja
@@ -0,0 +1,26 @@
+{% macro insert(device_profile) %}
+Device profile
+
+
+ {% for question in device_profile %}
+
+
{{loop.index}}.
+
{{ question['question'] }}
+
+ {% if question['answer'] is string %}
+ {{ question['answer'] }}
+ {% elif question['answer'] is sequence %}
+
+ {% for answer in question['answer'] %}
+ {{ answer }}
+ {% endfor %}
+
+ {% endif %}
+
+
+ {% endfor %}
+
+{% endmacro %}
\ No newline at end of file
diff --git a/resources/test_packs/pilot/report_templates/header.jinja b/resources/test_packs/pilot/report_templates/header.jinja
new file mode 100644
index 000000000..2e020f558
--- /dev/null
+++ b/resources/test_packs/pilot/report_templates/header.jinja
@@ -0,0 +1,33 @@
+{% macro insert(is_first, device, logo, icon) %}
+{% if is_first %}
+
+
-
-
+
+
+
+
+
+
+ Expiry
+ Length
+ Type
+ Port number
+ Signed by
+
+
+
+
+ 2049-12-31 23:59:59
+ 779
+ EC
+ 47188
+ None
+
+
+
+
+
+
Certificate Information
+
+
+
+ Property
+ Value
+
+
+
- Expiry
- Length
- Type
- Port number
- Signed by
+ Version
+ 3 (0x2)
-
-
-
- 2049-12-31 23:59:59
- 779
- EC
- 47188
- None
+ Signature Alg.
+ sha256WithRSAEncryption
-
-
-
-
-
-
Certificate Information
-
-
-
- Property
- Value
+ Validity from
+ 2023-03-29 18:37:51
-
-
-
- Version
- 3 (0x2)
-
-
- Signature Alg.
- sha256WithRSAEncryption
-
-
- Validity from
- 2023-03-29 18:37:51
-
-
- Valid to
- 2049-12-31 23:59:59
-
-
-
-
-
-
-
Subject Information
-
-
-
- Property
- Value
+ Valid to
+ 2049-12-31 23:59:59
-
-
-
- C
- US
-
-
-
- ST
- Pennsylvania
-
-
-
- L
- Coopersburg
-
-
-
- O
- Lutron Electronics Co.\, Inc.
-
-
+
+
+
+
+
Subject Information
+
+
- CN
- athena04E580B9
+ Property
+ Value
-
+
+
+
+ C
+ US
+
+
+ ST
+ Pennsylvania
+
+
+ L
+ Coopersburg
+
+
+ O
+ Lutron Electronics Co.\, Inc.
+
+
+ CN
+ athena04E580B9
+
-
-
-
Certificate Extensions
+
Certificate Extensions
@@ -366,45 +384,94 @@ Certificate Extensions
-
- authorityKeyIdentifier
- key_identifier=accca4f9bd2a47dae81a8f4c87ed2c8edcfd07bf, authority_cert_issuer=None, authority_cert_serial_number=None
-
-
-
- subjectKeyIdentifier
- digest=37d90a274635e963081520f98411bda240d30252
-
-
-
- basicConstraints
- ca=False, path_length=None
-
-
-
- keyUsage
- digital_signature=True, key_cert_sign=False, key_encipherment=False, crl_sign=False
-
-
-
-
-
Outbound Connections
+
+ authorityKeyIdentifier
+ key_identifier=accca4f9bd2a47dae81a8f4c87ed2c8edcfd07bf, authority_cert_issuer=None, authority_cert_serial_number=None
+
+
+ subjectKeyIdentifier
+ digest=37d90a274635e963081520f98411bda240d30252
+
+
+ basicConstraints
+ ca=False, path_length=None
+
+
+ keyUsage
+ digital_signature=True, key_cert_sign=False, key_encipherment=False, crl_sign=False
+
+
+
+
+
+
+
+
+
+
+
+
+
Outbound Connections
- Destination IP
- Port
+ Destination IP
+ Port
-
- 224.0.0.251 5353
- 209.244.0.3 Unknown
- 3.227.250.136 443
- 3.227.203.88 443
- 34.226.101.252 8883
- 3.227.250.208 443
- 52.94.225.110 443
-
-
-
-
\ No newline at end of file
+
+
+ 224.0.0.251
+ 5353
+
+
+ 209.244.0.3
+ Unknown
+
+
+ 3.227.250.136
+ 443
+
+
+ 3.227.203.88
+ 443
+
+
+ 34.226.101.252
+ 8883
+
+
+ 3.227.250.208
+ 443
+
+
+ 52.94.225.110
+ 443
+
+
+
+
+
+
+
+
diff --git a/testing/unit/tls/reports/tls_report_no_cert_local.html b/testing/unit/tls/reports/tls_report_no_cert_local.html
index c025ee9e8..c641abbf0 100644
--- a/testing/unit/tls/reports/tls_report_no_cert_local.html
+++ b/testing/unit/tls/reports/tls_report_no_cert_local.html
@@ -1,5 +1,31 @@
-TLS Module
-
-
- No TLS certificates found on the device
-
\ No newline at end of file
+
+
+
+
+
TLS Module
+
+
+ No TLS certificates found on the device
+
+
+
+
+
+
diff --git a/testing/unit/tls/reports/tls_report_single.html b/testing/unit/tls/reports/tls_report_single.html
index 6106068a6..4fb2be16d 100644
--- a/testing/unit/tls/reports/tls_report_single.html
+++ b/testing/unit/tls/reports/tls_report_single.html
@@ -1,118 +1,115 @@
-TLS Module
-
-
-
+
+
+
+
TLS Module
+
+
+
+ Expiry
+ Length
+ Type
+ Port number
+ Signed by
+
+
+
+
+ 2027-09-21 19:57:57
+ 901
+ RSA
+ 443
+ BuildingsIoT RSA Signing CA
+
+
+
+
+
+
Certificate Information
+
+
+
+ Property
+ Value
+
+
+
- Expiry
- Length
- Type
- Port number
- Signed by
+ Version
+ 1 (0x0)
-
-
-
- 2027-09-21 19:57:57
- 901
- RSA
- 443
- BuildingsIoT RSA Signing CA
+ Signature Alg.
+ sha256WithRSAEncryption
-
-
-
-
-
-
Certificate Information
-
-
-
- Property
- Value
+ Validity from
+ 2022-09-21 19:57:57
-
-
-
- Version
- 1 (0x0)
-
-
- Signature Alg.
- sha256WithRSAEncryption
-
-
- Validity from
- 2022-09-21 19:57:57
-
-
- Valid to
- 2027-09-21 19:57:57
-
-
-
-
-
-
-
Subject Information
-
-
-
- Property
- Value
+ Valid to
+ 2027-09-21 19:57:57
-
-
-
- C
- US
-
-
-
- ST
- California
-
-
-
- L
- Concord
-
-
-
- O
- BuildingsIoT
-
-
-
- OU
- Software
-
-
+
+
+
+
+
Subject Information
+
+
- CN
- EasyIO_FS-32
+ Property
+ Value
-
+
+
+
+ C
+ US
+
+
+ ST
+ California
+
+
+ L
+ Concord
+
+
+ O
+ BuildingsIoT
+
+
+ OU
+ Software
+
+
+ CN
+ EasyIO_FS-32
+
+
-
-
Outbound Connections
-
-
-
- Destination IP
- Port
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
diff --git a/testing/unit/tls/tls_module_test.py b/testing/unit/tls/tls_module_test.py
index f42c7e9d4..205280329 100644
--- a/testing/unit/tls/tls_module_test.py
+++ b/testing/unit/tls/tls_module_test.py
@@ -71,7 +71,7 @@ def security_tls_v1_2_server_test(self):
tls_version='1.2')
tls_1_3_results = None, 'No TLS 1.3'
test_results = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertTrue(test_results[0])
# Test 1.2 server when 1.3 connection is established
@@ -80,7 +80,7 @@ def security_tls_v1_2_for_1_3_server_test(self):
tls_1_3_results = TLS_UTIL.validate_tls_server('google.com',
tls_version='1.3')
test_results = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertTrue(test_results[0])
# Test 1.2 server when 1.2 and 1.3 connection is established
@@ -90,7 +90,7 @@ def security_tls_v1_2_for_1_2_and_1_3_server_test(self):
tls_1_3_results = TLS_UTIL.validate_tls_server('google.com',
tls_version='1.3')
test_results = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertTrue(test_results[0])
# Test 1.2 server when 1.2 and failed 1.3 connection is established
@@ -99,7 +99,7 @@ def security_tls_v1_2_for_1_2_and_1_3_fail_server_test(self):
tls_version='1.2')
tls_1_3_results = False, 'Signature faild'
test_results = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertTrue(test_results[0])
# Test 1.2 server when 1.3 and failed 1.2 connection is established
@@ -108,10 +108,10 @@ def security_tls_v1_2_for_1_3_and_1_2_fail_server_test(self):
tls_version='1.3')
tls_1_2_results = False, 'Signature faild'
test_results = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertTrue(test_results[0])
- def security_tls_server_results_test(self, ):
+ def security_tls_server_results_test(self):
# Generic messages to test they are passing through
# to the results as expected
fail_message = 'Certificate not validated'
@@ -121,74 +121,75 @@ def security_tls_server_results_test(self, ):
# Both None
tls_1_2_results = None, none_message
tls_1_3_results = None, none_message
- expected = None, (f'TLS 1.2 not validated: {none_message}\n'
- f'TLS 1.3 not validated: {none_message}')
+ expected = None, (f'TLS 1.2 not validated on port 443: {none_message}\n'
+ f'TLS 1.3 not validated on port 443: {none_message}')
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# TLS 1.2 Pass and TLS 1.3 None
tls_1_2_results = True, success_message
- expected = True, f'TLS 1.2 validated: {success_message}'
+ expected = True, f'TLS 1.2 validated on port 443: {success_message}'
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# TLS 1.2 Fail and TLS 1.3 None
tls_1_2_results = False, fail_message
- expected = False, f'TLS 1.2 not validated: {fail_message}'
+ expected = False, f'TLS 1.2 not validated on port 443: {fail_message}'
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# TLS 1.3 Pass and TLS 1.2 None
tls_1_2_results = None, fail_message
tls_1_3_results = True, success_message
- expected = True, f'TLS 1.3 validated: {success_message}'
+ expected = True, f'TLS 1.3 validated on port 443: {success_message}'
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# TLS 1.3 Fail and TLS 1.2 None
tls_1_3_results = False, fail_message
- expected = False, f'TLS 1.3 not validated: {fail_message}'
+ expected = False, f'TLS 1.3 not validated on port 443: {fail_message}'
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# TLS 1.2 Pass and TLS 1.3 Pass
tls_1_2_results = True, success_message
tls_1_3_results = True, success_message
- expected = True, (f'TLS 1.2 validated: {success_message}\n'
- f'TLS 1.3 validated: {success_message}')
+ expected = True, (f'TLS 1.2 validated on port 443: {success_message}\n'
+ f'TLS 1.3 validated on port 443: {success_message}')
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
+
self.assertEqual(result, expected)
# TLS 1.2 Pass and TLS 1.3 Fail
tls_1_2_results = True, success_message
tls_1_3_results = False, fail_message
- expected = True, (f'TLS 1.2 validated: {success_message}\n'
- f'TLS 1.3 not validated: {fail_message}')
+ expected = True, (f'TLS 1.2 validated on port 443: {success_message}\n'
+ f'TLS 1.3 not validated on port 443: {fail_message}')
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# TLS 1.2 Fail and TLS 1.2 Pass
tls_1_2_results = False, fail_message
tls_1_3_results = True, success_message
- expected = True, (f'TLS 1.2 not validated: {fail_message}\n'
- f'TLS 1.3 validated: {success_message}')
+ expected = True, (f'TLS 1.2 not validated on port 443: {fail_message}\n'
+ f'TLS 1.3 validated on port 443: {success_message}')
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# TLS 1.2 Fail and TLS 1.2 Fail
tls_1_3_results = False, fail_message
- expected = False, (f'TLS 1.2 not validated: {fail_message}\n'
- f'TLS 1.3 not validated: {fail_message}')
+ expected = False, (f'TLS 1.2 not validated on port 443: {fail_message}\n'
+ f'TLS 1.3 not validated on port 443: {fail_message}')
result = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertEqual(result, expected)
# Test 1.2 server when 1.3 and 1.2 failed connection is established
@@ -196,7 +197,7 @@ def security_tls_v1_2_fail_server_test(self):
tls_1_2_results = False, 'Signature faild'
tls_1_3_results = False, 'Signature faild'
test_results = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertFalse(test_results[0])
# Test 1.2 server when 1.3 and 1.2 failed connection is established
@@ -205,7 +206,7 @@ def security_tls_v1_2_none_server_test(self):
tls_1_2_results = None, 'No cert'
tls_1_3_results = None, 'No cert'
test_results = TLS_UTIL.process_tls_server_results(tls_1_2_results,
- tls_1_3_results)
+ tls_1_3_results,port=443)
self.assertIsNone(test_results[0])
def security_tls_v1_3_server_test(self):
@@ -608,7 +609,7 @@ def download_public_cert(self, hostname, port=443):
suite.addTest(TLSModuleTest('security_tls_v1_2_fail_server_test'))
suite.addTest(TLSModuleTest('security_tls_v1_2_none_server_test'))
- # # TLS 1.3 server tests
+ # TLS 1.3 server tests
suite.addTest(TLSModuleTest('security_tls_v1_3_server_test'))
# TLS client tests