diff --git a/backend/db/migrations/R__Create-Test-Data.sql b/backend/db/migrations/R__Create-Test-Data.sql index 648daca8a..6b975d01b 100644 --- a/backend/db/migrations/R__Create-Test-Data.sql +++ b/backend/db/migrations/R__Create-Test-Data.sql @@ -546,7 +546,7 @@ VALUES('23-006887', 'Caller reporting a dumping site off the side of Hwy 3, goin ON CONFLICT DO NOTHING; INSERT INTO public.complaint (complaint_identifier, detail_text, caller_name, caller_address, caller_email, caller_phone_1, caller_phone_2, caller_phone_3, location_summary_text, location_detailed_text, incident_datetime, incident_reported_datetime, referred_by_agency_other_text, create_user_id, create_timestamp, update_user_id, update_timestamp, referred_by_agency_code, owned_by_agency_code, complaint_status_code, geo_organization_unit_code, location_geometry_point) -VALUES('23-006888', 'Caller was involved in an altercation yesterday with a person who was exceeding the Caller’s understanding of the limit. SUBs were attempting to catch 5 fish, of each type, each person (total 20.) SUBs male and their wife. Caller requesting CO clarification regarding fish quotas for region 3. Caller has contacted front counter BC, who referred the answer to COS.', 'Kelsey', '135 fake st', NULL, '555-555-5565', NULL, NULL, 'Keefes Landing Rd and Danskin Rd', 'tester call description 8', '2023-04-11 07:24:00.000', '2023-04-10 07:24:00.000', 'test2', 'FLYWAY', '2023-06-29 22:16:16.754', 'FLYWAY', '2023-06-29 22:16:16.754', 'BYLAW', 'COS', 'OPEN', 'DANSKIN', 'SRID=4326;POINT (0 0)'::public.geometry) +VALUES('23-006888', 'Caller was involved in an altercation yesterday with a person who was exceeding the Caller’s understanding of the limit. SUBs were attempting to catch 5 fish, of each type, each person (total 20.) SUBs male and their wife. Caller requesting CO clarification regarding fish quotas for region 3. Caller has contacted front counter BC, who referred the answer to COS.', 'Kelsey', '135 fake st', NULL, '555-555-5565', NULL, NULL, 'Keefes Landing Rd and Danskin Rd', 'tester call description 8', '2023-04-11 07:24:00.000', '2023-04-10 07:24:00.000', 'test2', 'FLYWAY', '2023-06-29 22:16:16.754', 'FLYWAY', '2023-06-29 22:16:16.754', 'BYLAW', 'COS', 'OPEN', 'DANSKIN', 'SRID=4326;POINT (53.991532 -125.7878868)'::public.geometry) ON CONFLICT DO NOTHING; INSERT INTO public.complaint (complaint_identifier, detail_text, caller_name, caller_address, caller_email, caller_phone_1, caller_phone_2, caller_phone_3, location_summary_text, location_detailed_text, incident_datetime, incident_reported_datetime, referred_by_agency_other_text, create_user_id, create_timestamp, update_user_id, update_timestamp, referred_by_agency_code, owned_by_agency_code, complaint_status_code, geo_organization_unit_code, location_geometry_point) @@ -1195,7 +1195,7 @@ VALUES('23-007022', 'Calling to report that a moose was hit by a car this mornin ON CONFLICT DO NOTHING; INSERT INTO public.complaint (complaint_identifier, detail_text, caller_name, caller_address, caller_email, caller_phone_1, caller_phone_2, caller_phone_3, location_summary_text, location_detailed_text, incident_datetime, incident_reported_datetime, referred_by_agency_other_text, create_user_id, create_timestamp, update_user_id, update_timestamp, referred_by_agency_code, owned_by_agency_code, complaint_status_code, geo_organization_unit_code, location_geometry_point) -VALUES('23-007023', 'Caller reporting plastic garbage dumped in the shallows of Lake near the mouth of the creek When caller picked up plastics she saw a small amount of paint spill from the bag. The water is fish baring and caller can see a little cloud of material. Caller does not know how much pain was originally in the plastic bag. Caller threw out the garbage but took a picture.', 'Chris', '130 fake st', NULL, '555-555-5560', '555-555-5568', NULL, '5807 crystal Rd', NULL, '2023-04-06 07:24:00.000', '2023-04-05 07:24:00.000', NULL, 'FLYWAY','2023-06-29 22:16:16.754', 'FLYWAY','2023-06-29 22:16:16.754', NULL, 'COS', 'OPEN', 'ROSELAK', 'SRID=4326;POINT (0 0)'::public.geometry) +VALUES('23-007023', 'Caller reporting plastic garbage dumped in the shallows of Lake near the mouth of the creek When caller picked up plastics she saw a small amount of paint spill from the bag. The water is fish baring and caller can see a little cloud of material. Caller does not know how much pain was originally in the plastic bag. Caller threw out the garbage but took a picture.', 'Chris', '130 fake st', NULL, '555-555-5560', '555-555-5568', NULL, '5807 crystal Rd', NULL, '2023-04-06 07:24:00.000', '2023-04-05 07:24:00.000', NULL, 'FLYWAY','2023-06-29 22:16:16.754', 'FLYWAY','2023-06-29 22:16:16.754', NULL, 'COS', 'OPEN', 'ROSELAK', 'SRID=4326;POINT (50.1705571 -115.6849567)'::public.geometry) ON CONFLICT DO NOTHING; INSERT INTO public.complaint (complaint_identifier, detail_text, caller_name, caller_address, caller_email, caller_phone_1, caller_phone_2, caller_phone_3, location_summary_text, location_detailed_text, incident_datetime, incident_reported_datetime, referred_by_agency_other_text, create_user_id, create_timestamp, update_user_id, update_timestamp, referred_by_agency_code, owned_by_agency_code, complaint_status_code, geo_organization_unit_code, location_geometry_point) @@ -1271,3 +1271,11 @@ INSERT INTO public.allegation_complaint (in_progress_ind,observed_ind,suspect_wi (true,false,NULL,'FLYWAY','2023-07-26 19:25:34.66322','FLYWAY','2023-07-26 19:25:34.66322','23-007028','RECREATN'), (true,true,NULL,'FLYWAY','2023-07-26 19:25:34.66322','FLYWAY','2023-07-26 19:25:34.66322','23-007029','FISHERY') ON CONFLICT DO NOTHING; + +UPDATE public.complaint t +set location_geometry_point = 'POINT (50.1705571 -115.6849567)' +where t.complaint_identifier = '23-007023'; + +UPDATE public.complaint t +set location_geometry_point = 'POINT (53.991532 -125.7878868)' +where t.complaint_identifier = '23-006888'; \ No newline at end of file diff --git a/frontend/Caddyfile b/frontend/Caddyfile index 651e6f8e2..69bf0b467 100644 --- a/frontend/Caddyfile +++ b/frontend/Caddyfile @@ -43,7 +43,7 @@ Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate" X-Content-Type-Options "nosniff" Strict-Transport-Security "max-age=31536000" - Content-Security-Policy "default-src 'self' https://*.gov.bc.ca data:; script-src https://*.gov.bc.ca 'self' 'unsafe-eval' https://www2.gov.bc.ca ;style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://use.fontawesome.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https://fonts.googleapis.com http://www.w3.org https://*.gov.bc.ca" + Content-Security-Policy "default-src 'self' https://*.gov.bc.ca data:; script-src https://*.gov.bc.ca 'self' 'unsafe-eval' https://www2.gov.bc.ca ;style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://use.fontawesome.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https://fonts.googleapis.com http://www.w3.org https://*.gov.bc.ca https://*.tile.openstreetmap.org" Referrer-Policy "same-origin" Feature-Policy "fullscreen 'self'; camera 'none'; microphone 'none'" } diff --git a/frontend/cypress/e2e/allegation-details-edit.cy.ts b/frontend/cypress/e2e/allegation-details-edit.cy.ts index 2f1b505b2..ba4327233 100644 --- a/frontend/cypress/e2e/allegation-details-edit.cy.ts +++ b/frontend/cypress/e2e/allegation-details-edit.cy.ts @@ -3,40 +3,13 @@ Test to verify that the user is able to click the edit button on the wildlife contacts details page and see all the inputs */ describe("Complaint Edit Page spec - Edit Allegation View", () => { - before(function () { + beforeEach(function () { cy.viewport("macbook-16"); cy.kcLogout().kcLogin(); }); it("Navigate to the Complaint Edit page & check inputs", () => { - cy.visit("/"); - - //-- click on Allegation tab - cy.get("#ers-tab").click({ force: true }); - - //this is our first test that is run after a deployment... give it a bit of extra time to finish while things spin up. - cy.get('.comp-loader-overlay', {timeout: 30000}).should('exist'); - cy.get('.comp-loader-overlay', {timeout: 30000}).should('not.exist'); - - //-- check to make sure there are items in the table - cy.get("#comp-table") - .find("tr") - .then(({ length }) => { - expect(length, "rows N").to.be.gt(0); - }); - - cy.get( - "#comp-table > tbody > tr:nth-child(2) td.comp-location-cell.comp-cell" - ).click({ force: true }); - - //this is our first test that is run after a deployment... give it a bit of extra time to finish while things spin up. - cy.get('.comp-loader-overlay', {timeout: 30000}).should('exist'); - cy.get('.comp-loader-overlay', {timeout: 30000}).should('not.exist'); - - cy.window().scrollTo("top"); - - - cy.get("#details-screen-edit-button").click({ force: true }); + cy.navigateToAllegationEditScreen("23-006888"); // Note: if the layout of this page changes, these selectors that use classes may break @@ -211,4 +184,10 @@ describe("Complaint Edit Page spec - Edit Allegation View", () => { cy.get("#subject-of-complaint-pair-id textarea").should("exist"); }); + + it("it has a map on screen with a marker at the correct location", function () { + cy.navigateToAllegationEditScreen("23-006888"); + cy.verifyMapMarkerExists(); + }); + }); \ No newline at end of file diff --git a/frontend/cypress/e2e/allegation-details.cy.ts b/frontend/cypress/e2e/allegation-details.cy.ts index d703c76c0..11167e2d3 100644 --- a/frontend/cypress/e2e/allegation-details.cy.ts +++ b/frontend/cypress/e2e/allegation-details.cy.ts @@ -64,25 +64,7 @@ describe("COMPENF-37 Display ECR Details", () => { }); it("it has correct call details", () => { - //-- navigate to application root - cy.visit("/"); - - //-- click on HWCR tab - cy.get("#ers-tab").click({ force: true }); - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); - cy.get("#comp-zone-close").click({ force: true }); //clear zone filter so this complaint is in the list view - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); - - //-- check to make sure there are items in the table - cy.get("#comp-table") - .find("tr") - .then(({ length }) => { - expect(length, "rows N").to.be.gt(0); - }); - - cy.get("#comp-table > tbody > tr > td.comp-small-cell").contains("23-007890").click({ force: true }); + cy.navigateToAllegationDetailsScreen("23-007890"); //-- verify the call details block cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-right-28.col-md-6 > div:nth-child(1) > p").contains(callDetails.description) @@ -96,5 +78,9 @@ describe("COMPENF-37 Display ECR Details", () => { cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(7) > span.comp-details-content").contains(callDetails.region) }); + it("it has a map on screen with a marker at the correct location", function () { + cy.navigateToAllegationDetailsScreen("23-006888"); + cy.verifyMapMarkerExists(); + }); }); diff --git a/frontend/cypress/e2e/hwcr-details-edit.cy.ts b/frontend/cypress/e2e/hwcr-details-edit.cy.ts index 310ee3c31..c62d35c65 100644 --- a/frontend/cypress/e2e/hwcr-details-edit.cy.ts +++ b/frontend/cypress/e2e/hwcr-details-edit.cy.ts @@ -3,37 +3,13 @@ Test to verify that the user is able to click the edit button on the wildlife contacts details page and see all the inputs */ describe("Complaint Edit Page spec - Edit View", () => { - before(function () { + beforeEach(function () { cy.viewport("macbook-16"); cy.kcLogout().kcLogin(); }); - it("Navigate to the Complaint Edit page & check inputs", () => { - cy.visit("/"); - - //-- click on HWCR tab - cy.get("#hwcr-tab").click({ force: true }); - - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); - - //-- check to make sure there are items in the table - cy.get("#comp-table") - .find("tr") - .then(({ length }) => { - expect(length, "rows N").to.be.gt(0); - }); - - cy.get( - "#comp-table > tbody > tr:nth-child(1) td.comp-location-cell.comp-cell" - ).click({ force: true }); - - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); - - cy.window().scrollTo("top"); - - cy.get("#details-screen-edit-button").click({ force: true }); + it("Navigate to the Complaint Edit page & check inputs", function() { + cy.navigateToHWLCEditScreen("23-007023"); // Note: if the layout of this page changes, these selectors that use classes may break // Check the First Section inputs @@ -189,4 +165,11 @@ describe("Complaint Edit Page spec - Edit View", () => { }); cy.get("#referred-pair-id input").should("exist"); }); + + it("it has a map on screen with a marker at the correct location", () => { + cy.navigateToHWLCEditScreen("23-007023"); + + cy.verifyMapMarkerExists(); + + }); }); \ No newline at end of file diff --git a/frontend/cypress/e2e/hwcr-details.cy.ts b/frontend/cypress/e2e/hwcr-details.cy.ts index c8a3b038e..0ca1acbcb 100644 --- a/frontend/cypress/e2e/hwcr-details.cy.ts +++ b/frontend/cypress/e2e/hwcr-details.cy.ts @@ -1,25 +1,26 @@ describe("COMPENF-35 Display HWCR Details", () => { - const callDetails = { - description: "Calling to report a black bear getting into the garbage on a regular basis. Also wanted to confirm that residents of the trailer home park could call to report sightings themselves", + const callDetails = { + description: + "Calling to report a black bear getting into the garbage on a regular basis. Also wanted to confirm that residents of the trailer home park could call to report sightings themselves", location: "644 Pine Street", - locationDescription: "", + locationDescription: "", incidentTime: "2022-12-19T08:51:00.000Z", attractants: ["Garbage", "Freezer", "Compost"], community: "Kamloops", office: "Kamloops", zone: "Thompson Nicola", - region: "Thompson Cariboo" - } - - const callerInformation = { - name: "Phoebe", - phone: "250-556-1234", - cell: "", - alternate: "", - address: "437 Fake St", - email: "tester@gmail.com", - referred: "Conservation Officer Service" - } + region: "Thompson Cariboo", + }; + + const callerInformation = { + name: "Phoebe", + phone: "250-556-1234", + cell: "", + alternate: "", + address: "437 Fake St", + email: "tester@gmail.com", + referred: "Conservation Officer Service", + }; beforeEach(function () { cy.viewport("macbook-16"); @@ -33,7 +34,7 @@ describe("COMPENF-35 Display HWCR Details", () => { //-- click on HWCR tab cy.get("#hwcr-tab").click({ force: true }); - cy.get('.comp-loader-overlay').should('not.exist'); + cy.get(".comp-loader-overlay").should("not.exist"); //-- check to make sure there are items in the table cy.get("#comp-table") @@ -49,9 +50,9 @@ describe("COMPENF-35 Display HWCR Details", () => { //-- click on HWCR tab cy.get("#hwcr-tab").click({ force: true }); - cy.get('.comp-loader-overlay').should('not.exist'); + cy.get(".comp-loader-overlay").should("not.exist"); cy.get("#comp-zone-close").click({ force: true }); //clear zone filter so this complaint is in the list view - cy.get('.comp-loader-overlay').should('not.exist'); + cy.get(".comp-loader-overlay").should("not.exist"); //-- check to make sure there are items in the table cy.get("#comp-table") .find("tr") @@ -59,11 +60,13 @@ describe("COMPENF-35 Display HWCR Details", () => { expect(length, "rows N").to.be.gt(0); }); - cy.get("#comp-table > tbody > tr > td.comp-small-cell").contains("23-000076").click({ force: true }); + cy.get("#comp-table > tbody > tr > td.comp-small-cell") + .contains("23-000076") + .click({ force: true }); //-- verify the right complaint identifier is selected and the animal type - cy.get(".comp-box-complaint-id").contains("23-000076") - cy.get(".comp-box-species-type").contains("Black Bear") + cy.get(".comp-box-complaint-id").contains("23-000076"); + cy.get(".comp-box-species-type").contains("Black Bear"); }); it("it has correct call details", () => { @@ -72,14 +75,14 @@ describe("COMPENF-35 Display HWCR Details", () => { //-- click on HWCR tab cy.get("#hwcr-tab").click({ force: true }); - - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); + + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); cy.get("#comp-zone-close").click({ force: true }); //clear zone filter so this complaint is in the list view - - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); + + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); //-- check to make sure there are items in the table cy.get("#comp-table") @@ -88,32 +91,45 @@ describe("COMPENF-35 Display HWCR Details", () => { expect(length, "rows N").to.be.gt(0); }); - cy.get("#comp-table > tbody > tr > td.comp-small-cell").contains("23-000076").click({ force: true }); + cy.get("#comp-table > tbody > tr > td.comp-small-cell") + .contains("23-000076") + .click({ force: true }); //-- verify the call details block - cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-right-28.col-md-6 > div:nth-child(1) > p").contains(callDetails.description) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(1) > div.comp-details-content").contains(callDetails.location); - cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(4) > span.comp-details-content").contains(callDetails.community) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(5) > span.comp-details-content").contains(callDetails.office) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(6) > span.comp-details-content").contains(callDetails.zone) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(7) > span.comp-details-content").contains(callDetails.region) - + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-right-28.col-md-6 > div:nth-child(1) > p" + ).contains(callDetails.description); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(1) > div.comp-details-content" + ).contains(callDetails.location); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(4) > span.comp-details-content" + ).contains(callDetails.community); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(5) > span.comp-details-content" + ).contains(callDetails.office); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(6) > span.comp-details-content" + ).contains(callDetails.zone); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(4) > div > div > div.comp-padding-left-28.col-md-6 > div:nth-child(7) > span.comp-details-content" + ).contains(callDetails.region); }); - it("it has correct call details", () => { + it("it has correct call information details", () => { //-- navigate to application root cy.visit("/"); //-- click on HWCR tab cy.get("#hwcr-tab").click({ force: true }); - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); cy.get("#comp-zone-close").click({ force: true }); //clear zone filter so this complaint is in the list view - cy.get('.comp-loader-overlay').should('exist'); - cy.get('.comp-loader-overlay').should('not.exist'); + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); //-- check to make sure there are items in the table cy.get("#comp-table") @@ -122,25 +138,54 @@ describe("COMPENF-35 Display HWCR Details", () => { expect(length, "rows N").to.be.gt(0); }); - cy.get("#comp-table > tbody > tr > td.comp-small-cell").contains("23-000076").click({ force: true }); + cy.get("#comp-table > tbody > tr > td.comp-small-cell") + .contains("23-000076") + .click({ force: true }); //-- verify the call details block - cy.get("#root > div > div.comp-main-content > div > div:nth-child(5) > div > div > div:nth-child(1) > div:nth-child(1) > div.comp-details-content").contains(callerInformation.name) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(5) > div > div > div:nth-child(1) > div:nth-child(2) > div.comp-details-content").contains(callerInformation.phone) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(5) > div > div > div:nth-child(1) > div:nth-child(3) > div.comp-details-content") - .should(($el) => { + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(6) > div > div > div:nth-child(1) > div:nth-child(1) > div.comp-details-content" + ).contains(callerInformation.name); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(6) > div > div > div:nth-child(1) > div:nth-child(2) > div.comp-details-content" + ).contains(callerInformation.phone); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(6) > div > div > div:nth-child(1) > div:nth-child(3) > div.comp-details-content" + ).should(($el) => { expect($el.text().trim()).equal(callerInformation.cell); }); - cy.get("#root > div > div.comp-main-content > div > div:nth-child(5) > div > div > div:nth-child(1) > div:nth-child(4) > div.comp-details-content") - .should(($el) => { + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(6) > div > div > div:nth-child(1) > div:nth-child(4) > div.comp-details-content" + ).should(($el) => { expect($el.text().trim()).equal(callerInformation.alternate); }); - cy.get("#root > div > div.comp-main-content > div > div:nth-child(5) > div > div > div:nth-child(2) > div:nth-child(1) > div.comp-details-content").contains(callerInformation.address) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(5) > div > div > div:nth-child(2) > div:nth-child(2) > div.comp-details-content").contains(callerInformation.email) - cy.get("#root > div > div.comp-main-content > div > div:nth-child(5) > div > div > div:nth-child(2) > div:nth-child(3) > div.comp-details-content").contains(callerInformation.referred) + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(6) > div > div > div:nth-child(2) > div:nth-child(1) > div.comp-details-content" + ).contains(callerInformation.address); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(6) > div > div > div:nth-child(2) > div:nth-child(2) > div.comp-details-content" + ).contains(callerInformation.email); + cy.get( + "#root > div > div.comp-main-content > div > div:nth-child(6) > div > div > div:nth-child(2) > div:nth-child(3) > div.comp-details-content" + ).contains(callerInformation.referred); }); -}); + it("it has a map on screen with a marker at the correct location", function () { + cy.navigateToHWLCDetailsScreen("23-007023"); -//#comp-table > tbody > tr:nth-child(5) > td.comp-nature-complaint-cell.comp-cell \ No newline at end of file + // get the x and y coordinates + cy.get("#call-details-x-coordinate-div") + .invoke("text") + .as("xCoordinateDivContent") + .should("exist"); + + cy.get("#call-details-y-coordinate-div") + .invoke("text") + .as("yCoordinateDivContent") + .should("exist"); + + cy.verifyMapMarkerExists(); + + }); +}); diff --git a/frontend/cypress/e2e/leaflet.cy.ts b/frontend/cypress/e2e/leaflet.cy.ts new file mode 100644 index 000000000..84666e4d9 --- /dev/null +++ b/frontend/cypress/e2e/leaflet.cy.ts @@ -0,0 +1,38 @@ +import { MapOptions } from "leaflet"; + +describe("Test Mapping functionality", () => { + before(function () { + cy.viewport("macbook-16"); + cy.kcLogout().kcLogin(); + }); + + it("tests basic leaflet functions", function () { + // Create the map + cy.visit("/", { + onLoad: (contentWindow: any) => { + const { L } = contentWindow; + + const options: MapOptions = { + center: { lat: 40.731253, lng: -73.996139 }, + zoom: 10, + }; + + // Create the map + const map = L.map("root", options); + + L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { + attribution: 'Mascots', + }).addTo(map); + + // add a marker to the map + L.marker([50.1705571, -115.6849567]).addTo(map); + + map.zoomIn(); + map.zoomOut(); + + contentWindow.map = map; + }, + }); + cy.verifyMapMarkerExists(); + }); +}); \ No newline at end of file diff --git a/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts index a38cbb100..3bf09b0fd 100644 --- a/frontend/cypress/support/commands.ts +++ b/frontend/cypress/support/commands.ts @@ -5,152 +5,231 @@ // https://on.cypress.io/custom-commands // *********************************************** -const base64url = source => { - // Encode the input string as base64. - let encodedSource = btoa(source); - - // Replace any characters that are not URL-safe. - encodedSource = encodedSource - .replace(/\+/g, '-') - .replace(/\//g, '_') - .replace(/=+$/, ''); - - return encodedSource; - }; - - const sha256 = async plain => { - // encode as UTF-8. - const msgBuffer = new TextEncoder().encode(plain); - - // hash the message. - const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer); - - // convert ArrayBuffer to Array. - const hashArray = Array.from(new Uint8Array(hashBuffer)); - - // convert bytes to hex string. - const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join(''); - - return hashHex; - }; - - Cypress.Commands.add('kcLogin', () => { - Cypress.log({ name: 'Login to Keycloak' }); - - cy.log('Keyloak Login').then(async () => { - const authBaseUrl = Cypress.env('auth_base_url'); - const realm = Cypress.env('auth_realm'); - const client_id = Cypress.env('auth_client_id'); - const redirect_uri = Cypress.config('baseUrl') + '/login'; - - const scope = 'openid'; - const state = '123456'; - const nonce = '7890'; - const code_challenge_method = 'S256'; - const kc_idp_hint = 'idir'; - - // Generate a code verifier using a random string of 43-128 characters. - const code_verifier = - Cypress._.random(0, 1e10).toString(36) + Cypress._.random(0, 1e10).toString(36); - const code_challenge = base64url(await sha256(code_verifier)); - - // Make the initial request to the authentication endpoint. - cy.request({ - method: 'GET', - url: `${authBaseUrl}/realms/${realm}/protocol/openid-connect/auth`, - qs: { - client_id, - redirect_uri, - code_challenge_method, - code_challenge, - response_type: 'code', - scope, - state, - nonce, - kc_idp_hint, - }, - followRedirect: false, // Don't follow the redirect automatically. - }).then(response => { - // Extract the location header from the response to get the redirect URL. - const redirectUrls = response.headers.location; - const url = Array.isArray(redirectUrls) ? redirectUrls[0] : redirectUrls; - - // Visit redirect URL. - const credentials = { - username: Cypress.env('keycloak_user'), - password: Cypress.env('keycloak_password'), - url: url - }; - - // depending on if we're running the cypress tests locally or not, we may or may not ge a CORS error. - // If the keycloak login URL is the same as the application URL, then simply visit the URL; - // otherwise, will need to use cy.origin to avoid any CORS errors. - if (hasSameTopLevelDomain(Cypress.env('keycloak_login_url'), Cypress.config().baseUrl)) { - cy.visit(url); - // Log in the user and obtain an authorization code. - cy.get('[name="user"]').click(); - cy.get('[name="user"]').type(credentials.username); - cy.get('[name="password"]').click(); - cy.get('[name="password"]').type(credentials.password, {log: false}); - cy.get('[name="btnSubmit"]').click(); - } else { // different origin, so handle CORS errors - cy.visit("/"); - cy.on('uncaught:exception', (e) => { - if (e.message.includes('Unexpected')) { - // we expected this error, so let's ignore it - // and let the test continue - return false - } - }) - cy.origin( - Cypress.env('keycloak_login_url'), - { args: credentials }, - ({ username, password, url }) => { +const base64url = (source) => { + // Encode the input string as base64. + let encodedSource = btoa(source); + + // Replace any characters that are not URL-safe. + encodedSource = encodedSource + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/, ""); + + return encodedSource; +}; + +const sha256 = async (plain) => { + // encode as UTF-8. + const msgBuffer = new TextEncoder().encode(plain); + + // hash the message. + const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer); + + // convert ArrayBuffer to Array. + const hashArray = Array.from(new Uint8Array(hashBuffer)); + + // convert bytes to hex string. + const hashHex = hashArray + .map((b) => ("00" + b.toString(16)).slice(-2)) + .join(""); + + return hashHex; +}; + +Cypress.Commands.add("kcLogin", () => { + Cypress.log({ name: "Login to Keycloak" }); + + cy.log("Keyloak Login").then(async () => { + const authBaseUrl = Cypress.env("auth_base_url"); + const realm = Cypress.env("auth_realm"); + const client_id = Cypress.env("auth_client_id"); + const redirect_uri = Cypress.config("baseUrl") + "/login"; + + const scope = "openid"; + const state = "123456"; + const nonce = "7890"; + const code_challenge_method = "S256"; + const kc_idp_hint = "idir"; + + // Generate a code verifier using a random string of 43-128 characters. + const code_verifier = + Cypress._.random(0, 1e10).toString(36) + + Cypress._.random(0, 1e10).toString(36); + const code_challenge = base64url(await sha256(code_verifier)); + + // Make the initial request to the authentication endpoint. + cy.request({ + method: "GET", + url: `${authBaseUrl}/realms/${realm}/protocol/openid-connect/auth`, + qs: { + client_id, + redirect_uri, + code_challenge_method, + code_challenge, + response_type: "code", + scope, + state, + nonce, + kc_idp_hint, + }, + followRedirect: false, // Don't follow the redirect automatically. + }).then((response) => { + // Extract the location header from the response to get the redirect URL. + const redirectUrls = response.headers.location; + const url = Array.isArray(redirectUrls) ? redirectUrls[0] : redirectUrls; + + // Visit redirect URL. + const credentials = { + username: Cypress.env("keycloak_user"), + password: Cypress.env("keycloak_password"), + url: url, + }; + + // depending on if we're running the cypress tests locally or not, we may or may not ge a CORS error. + // If the keycloak login URL is the same as the application URL, then simply visit the URL; + // otherwise, will need to use cy.origin to avoid any CORS errors. + if ( + hasSameTopLevelDomain( + Cypress.env("keycloak_login_url"), + Cypress.config().baseUrl + ) + ) { + cy.visit(url); + // Log in the user and obtain an authorization code. + cy.get('[name="user"]').click(); + cy.get('[name="user"]').type(credentials.username); + cy.get('[name="password"]').click(); + cy.get('[name="password"]').type(credentials.password, { log: false }); + cy.get('[name="btnSubmit"]').click(); + } else { + // different origin, so handle CORS errors + cy.visit("/"); + cy.on("uncaught:exception", (e) => { + if (e.message.includes("Unexpected")) { + // we expected this error, so let's ignore it + // and let the test continue + return false; + } + }); + cy.origin( + Cypress.env("keycloak_login_url"), + { args: credentials }, + ({ username, password, url }) => { cy.visit(url); // Log in the user and obtain an authorization code. cy.get('[name="user"]').click(); cy.get('[name="user"]').type(username); cy.get('[name="password"]').click(); - cy.get('[name="password"]').type(password, {log: false}); + cy.get('[name="password"]').type(password, { log: false }); cy.get('[name="btnSubmit"]').click(); - }); - } - }); + } + ); + } }); }); - - Cypress.Commands.add('kcLogout', () => { - Cypress.log({ name: 'Logout' }); - const authBaseUrl = Cypress.env('auth_base_url'); - const realm = Cypress.env('auth_realm'); - cy.request({ - url: `${authBaseUrl}/realms/${realm}/protocol/openid-connect/logout`, - }); - cy.visit(Cypress.config().baseUrl); - cy.on('uncaught:exception', (e) => { - if (e.message.includes('Unexpected')) { - // we expected this error, so let's ignore it - // and let the test continue - return false - } - }) +}); +Cypress.Commands.add("kcLogout", () => { + Cypress.log({ name: "Logout" }); + const authBaseUrl = Cypress.env("auth_base_url"); + const realm = Cypress.env("auth_realm"); + cy.request({ + url: `${authBaseUrl}/realms/${realm}/protocol/openid-connect/logout`, }); + cy.visit(Cypress.config().baseUrl); + cy.on("uncaught:exception", (e) => { + if (e.message.includes("Unexpected")) { + // we expected this error, so let's ignore it + // and let the test continue + return false; + } + }); +}); + +Cypress.Commands.add("verifyMapMarkerExists", () => { + cy.get(".leaflet-container").should("exist"); + cy.get('.leaflet-marker-icon').should("exist"); +}); + +Cypress.Commands.add("navigateToHWLCDetailsScreen", (complaintIdentifier: string) => { + //-- navigate to application root + cy.visit("/"); + + //-- click on HWCR tab + cy.get("#hwcr-tab").click({ force: true }); + + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); + + cy.get("#comp-zone-close").click({ force: true }); //clear zone filter so this complaint is in the list view + + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); + + //-- check to make sure there are items in the table + cy.get("#comp-table") + .find("tr") + .then(({ length }) => { + expect(length, "rows N").to.be.gt(0); + }); + + cy.get("#comp-table > tbody > tr > td.comp-small-cell") + .contains(complaintIdentifier) + .click({ force: true }); + + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); +}); + +Cypress.Commands.add("navigateToHWLCEditScreen", (complaintIdentifier: string) => { + cy.navigateToHWLCDetailsScreen(complaintIdentifier); + cy.get("#details-screen-edit-button").click({ force: true }); +}); + +Cypress.Commands.add("navigateToAllegationDetailsScreen", (complaintIdentifier: string) => { + //-- navigate to application root + cy.visit("/"); + + //-- click on HWCR tab + cy.get("#ers-tab").click({ force: true }); + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); + cy.get("#comp-zone-close").click({ force: true }); //clear zone filter so this complaint is in the list view + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); + + //-- check to make sure there are items in the table + cy.get("#comp-table") + .find("tr") + .then(({ length }) => { + expect(length, "rows N").to.be.gt(0); + }); + + cy.get("#comp-table > tbody > tr > td.comp-small-cell") + .contains(complaintIdentifier) + .click({ force: true }); + cy.get(".comp-loader-overlay").should("exist"); + cy.get(".comp-loader-overlay").should("not.exist"); +}); + +Cypress.Commands.add("navigateToAllegationEditScreen", (complaintIdentifier: string) => { + cy.navigateToAllegationDetailsScreen(complaintIdentifier); + cy.get("#details-screen-edit-button").click({ force: true }); +}); + +function hasSameTopLevelDomain(url1: string, url2: string): boolean { + const tld1 = extractTopLevelDomain(url1); + const tld2 = extractTopLevelDomain(url2); + + return tld1 === tld2; +} + +function extractTopLevelDomain(url: string): string { + const domain = new URL(url).hostname; + const parts = domain.split("."); + const tld = parts.slice(-2).join("."); + + return tld; +} - function hasSameTopLevelDomain(url1: string, url2: string): boolean { - const tld1 = extractTopLevelDomain(url1); - const tld2 = extractTopLevelDomain(url2); - - return tld1 === tld2; - } - - function extractTopLevelDomain(url: string): string { - const domain = new URL(url).hostname; - const parts = domain.split('.'); - const tld = parts.slice(-2).join('.'); - - return tld; - } - - module.exports = {}; - \ No newline at end of file +module.exports = {}; diff --git a/frontend/cypress/support/index.ts b/frontend/cypress/support/index.ts index 2d59a72a0..4a97bfa6b 100644 --- a/frontend/cypress/support/index.ts +++ b/frontend/cypress/support/index.ts @@ -4,5 +4,10 @@ declare namespace Cypress { interface Chainable { kcLogin(): Chainable; kcLogout(): Chainable; + verifyMapMarkerExists() : Chainable; + navigateToHWLCDetailsScreen(complaintIdentifier: string) : Chainable; + navigateToHWLCEditScreen(complaintIdentifier: string) : Chainable; + navigateToAllegationDetailsScreen(complaintIdentifier: string) : Chainable; + navigateToAllegationEditScreen(complaintIdentifier: string) : Chainable; } } \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7d45b87af..7e877f0b2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,6 +10,9 @@ "license": "Apache-2.0", "dependencies": { "@faker-js/faker": "^8.0.2", + "@fortawesome/fontawesome-svg-core": "^6.4.2", + "@fortawesome/free-solid-svg-icons": "^6.4.2", + "@fortawesome/react-fontawesome": "^0.2.0", "@popperjs/core": "^2.11.7", "@react-aria/ssr": "^3.6.0", "@reduxjs/toolkit": "^1.8.1", @@ -20,11 +23,13 @@ "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.1.1", "@types/faker": "^5.5.9", + "@types/leaflet": "^1.9.3", "@types/lodash": "^4.14.195", "@types/node": "^18.0.0", "@types/react": "^18.0.6", "@types/react-datepicker": "^4.11.2", "@types/react-dom": "^18.0.2", + "@types/react-leaflet": "^3.0.0", "@types/react-transition-group": "^4.4.6", "@types/redux-persist": "^4.3.1", "@types/warning": "^3.0.0", @@ -41,13 +46,16 @@ "eslint-config-airbnb-typescript": "^17.0.0", "faker": "^5.5.3", "immutable": "^4.3.0", + "install": "^0.13.0", "invariant": "^2.2.4", "jsdom": "^21.0.0", "jwt-decode": "^3.1.2", "keycloak-js": "^21.0.0", + "leaflet": "^1.9.4", "linq-to-typescript": "^11.0.0", "lodash": "^4.17.21", "make-fetch-happen": "11.0.3", + "npm": "^9.8.1", "prop-types-extra": "^1.1.1", "react": "^18.2.0", "react-bootstrap": "^2.7.4", @@ -58,6 +66,7 @@ "react-dom": "^18.2.0", "react-icons": "^4.2.0", "react-is": "^16.13.1", + "react-leaflet": "^4.2.1", "react-lifecycles-compat": "^3.0.4", "react-redux": "^8.0.1", "react-router-dom": "^6.3.0", @@ -1995,7 +2004,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, "optional": true, "engines": { "node": ">=0.1.90" @@ -2580,6 +2588,51 @@ "@floating-ui/core": "^1.3.0" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz", + "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz", + "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz", + "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz", + "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -3697,6 +3750,16 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@react-leaflet/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz", + "integrity": "sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/@reduxjs/toolkit": { "version": "1.9.4", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.4.tgz", @@ -4314,6 +4377,11 @@ "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.5.9.tgz", "integrity": "sha512-uCx6mP3UY5SIO14XlspxsGjgaemrxpssJI0Ol+GfhxtcKpv9pgRZYsS4eeKeHVLje6Qtc8lGszuBI461+gVZBA==" }, + "node_modules/@types/geojson": { + "version": "7946.0.10", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz", + "integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==" + }, "node_modules/@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -4413,6 +4481,14 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/leaflet": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.3.tgz", + "integrity": "sha512-Caa1lYOgKVqDkDZVWkto2Z5JtVo09spEaUt2S69LiugbBpoqQu92HYFMGUbYezZbnBkyOxMNPXHSgRrRY5UyIA==", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/lodash": { "version": "4.14.195", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", @@ -4487,6 +4563,15 @@ "@types/react": "*" } }, + "node_modules/@types/react-leaflet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/react-leaflet/-/react-leaflet-3.0.0.tgz", + "integrity": "sha512-p8R9mVKbCDDqOdW+M6GyJJuFn6q+IgDFYavFiOIvaWHuOe5kIHZEtCy1pfM43JIA6JiB3D/aDoby7C51eO+XSg==", + "deprecated": "This is a stub types definition. react-leaflet provides its own type definitions, so you do not need this installed.", + "dependencies": { + "react-leaflet": "*" + } + }, "node_modules/@types/react-test-renderer": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz", @@ -6596,7 +6681,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", - "dev": true, "dependencies": { "string-width": "^4.2.0" }, @@ -10675,6 +10759,14 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -13853,6 +13945,11 @@ "node": "> 0.8" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -14665,6 +14762,158 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm": { + "version": "9.8.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-9.8.1.tgz", + "integrity": "sha512-AfDvThQzsIXhYgk9zhbk5R+lh811lKkLAeQMMhSypf1BM7zUafeIIBzMzespeuVEJ0+LvY36oRQYf7IKLzU3rw==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/run-script", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "cli-table3", + "columnify", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "npmlog", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "sigstore", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^6.3.0", + "@npmcli/config": "^6.2.1", + "@npmcli/fs": "^3.1.0", + "@npmcli/map-workspaces": "^3.0.4", + "@npmcli/package-json": "^4.0.1", + "@npmcli/promise-spawn": "^6.0.2", + "@npmcli/run-script": "^6.0.2", + "abbrev": "^2.0.0", + "archy": "~1.0.0", + "cacache": "^17.1.3", + "chalk": "^5.3.0", + "ci-info": "^3.8.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.3", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.2", + "glob": "^10.2.7", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^6.1.1", + "ini": "^4.1.1", + "init-package-json": "^5.0.0", + "is-cidr": "^4.0.2", + "json-parse-even-better-errors": "^3.0.0", + "libnpmaccess": "^7.0.2", + "libnpmdiff": "^5.0.19", + "libnpmexec": "^6.0.3", + "libnpmfund": "^4.0.19", + "libnpmhook": "^9.0.3", + "libnpmorg": "^5.0.4", + "libnpmpack": "^5.0.19", + "libnpmpublish": "^7.5.0", + "libnpmsearch": "^6.0.2", + "libnpmteam": "^5.0.3", + "libnpmversion": "^4.0.2", + "make-fetch-happen": "^11.1.1", + "minimatch": "^9.0.3", + "minipass": "^5.0.0", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^9.4.0", + "nopt": "^7.2.0", + "npm-audit-report": "^5.0.0", + "npm-install-checks": "^6.1.1", + "npm-package-arg": "^10.1.0", + "npm-pick-manifest": "^8.0.1", + "npm-profile": "^7.0.1", + "npm-registry-fetch": "^14.0.5", + "npm-user-validate": "^2.0.0", + "npmlog": "^7.0.1", + "p-map": "^4.0.0", + "pacote": "^15.2.0", + "parse-conflict-json": "^3.0.1", + "proc-log": "^3.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^2.1.0", + "semver": "^7.5.4", + "sigstore": "^1.7.0", + "ssri": "^10.0.4", + "supports-color": "^9.4.0", + "tar": "^6.1.15", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^5.0.0", + "which": "^3.0.1", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -14676,194 +14925,2909 @@ "node": ">=8" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/npm/node_modules/@colors/colors": { + "version": "1.5.0", + "inBundle": true, + "license": "MIT", + "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.1.90" } }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, "engines": { - "node": ">= 6" + "node": ">=12" } }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "inBundle": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": ">= 0.4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "6.3.0", + "inBundle": true, + "license": "ISC", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.0", + "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^5.0.0", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^4.0.0", + "@npmcli/query": "^3.0.0", + "@npmcli/run-script": "^6.0.0", + "bin-links": "^4.0.1", + "cacache": "^17.0.4", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^6.1.1", + "json-parse-even-better-errors": "^3.0.0", + "json-stringify-nice": "^1.1.4", + "minimatch": "^9.0.0", + "nopt": "^7.0.0", + "npm-install-checks": "^6.0.0", + "npm-package-arg": "^10.1.0", + "npm-pick-manifest": "^8.0.1", + "npm-registry-fetch": "^14.0.3", + "npmlog": "^7.0.1", + "pacote": "^15.0.8", + "parse-conflict-json": "^3.0.0", + "proc-log": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.2", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.1", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" }, "engines": { - "node": ">= 0.4" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "6.2.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^3.0.2", + "ci-info": "^3.8.0", + "ini": "^4.1.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "node_modules/npm/node_modules/@npmcli/disparity-colors": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "ansi-styles": "^4.3.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "3.1.0", + "inBundle": true, + "license": "ISC", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "semver": "^7.3.5" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", - "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", + "node_modules/npm/node_modules/@npmcli/git": { + "version": "4.1.0", + "inBundle": true, + "license": "ISC", "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" }, "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/object.hasown": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", - "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", + "inBundle": true, + "license": "ISC", "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "installed-package-contents": "lib/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "3.0.4", + "inBundle": true, + "license": "ISC", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "5.0.1", + "inBundle": true, + "license": "ISC", "dependencies": { - "ee-first": "1.1.1" + "cacache": "^17.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^15.0.0", + "semver": "^7.3.5" }, "engines": { - "node": ">= 0.8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", "engines": { - "node": ">= 0.8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/onetime": { - "version": "5.1.2", + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "4.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^4.1.0", + "glob": "^10.2.2", + "hosted-git-info": "^6.1.1", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "proc-log": "^3.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "6.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "6.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.1.0", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "1.0.2", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.1.0", + "tuf-js": "^1.1.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tootallnate/once": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/models": { + "version": "1.0.4", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "1.0.0", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abort-controller": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "6.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/npm/node_modules/agentkeepalive": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/are-we-there-yet": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^4.1.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "4.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.2.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/buffer": { + "version": "6.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/npm/node_modules/builtins": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "17.1.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.3.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "3.8.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "3.1.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^4.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/cli-table3": { + "version": "0.6.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/npm/node_modules/clone": { + "version": "1.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "6.0.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/color-support": { + "version": "1.1.3", + "inBundle": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/npm/node_modules/columnify": { + "version": "1.6.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/concat-map": { + "version": "0.0.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/console-control-strings": { + "version": "1.1.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.3.4", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/defaults": { + "version": "1.0.4", + "inBundle": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/delegates": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/depd": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/npm/node_modules/diff": { + "version": "5.1.0", + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/event-target-shim": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/events": { + "version": "3.3.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.1", + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/foreground-child": { + "version": "3.1.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/fs.realpath": { + "version": "1.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/function-bind": { + "version": "1.1.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/gauge": { + "version": "5.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "10.2.7", + "inBundle": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2", + "path-scurry": "^1.7.0" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/has": { + "version": "1.0.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/npm/node_modules/has-unicode": { + "version": "2.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "6.1.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.1", + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "5.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/humanize-ms": { + "version": "1.2.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "6.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/inflight": { + "version": "1.0.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/inherits": { + "version": "2.0.4", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/ini": { + "version": "4.1.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^10.0.0", + "promzard": "^1.0.0", + "read": "^2.0.0", + "read-package-json": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/ip": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "4.0.2", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^3.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/is-core-module": { + "version": "2.12.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "2.2.1", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "7.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^10.1.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "5.0.19", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/disparity-colors": "^3.0.0", + "@npmcli/installed-package-contents": "^2.0.2", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^9.0.0", + "npm-package-arg": "^10.1.0", + "pacote": "^15.0.8", + "tar": "^6.1.13" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "6.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/run-script": "^6.0.0", + "ci-info": "^3.7.1", + "npm-package-arg": "^10.1.0", + "npmlog": "^7.0.1", + "pacote": "^15.0.8", + "proc-log": "^3.0.0", + "read": "^2.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "4.0.19", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^6.3.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "9.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "5.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "5.0.19", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^6.3.0", + "@npmcli/run-script": "^6.0.0", + "npm-package-arg": "^10.1.0", + "pacote": "^15.0.8" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "7.5.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ci-info": "^3.6.1", + "normalize-package-data": "^5.0.0", + "npm-package-arg": "^10.1.0", + "npm-registry-fetch": "^14.0.3", + "proc-log": "^3.0.0", + "semver": "^7.3.7", + "sigstore": "^1.4.0", + "ssri": "^10.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "6.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "5.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^14.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "4.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^4.0.1", + "@npmcli/run-script": "^6.0.0", + "json-parse-even-better-errors": "^3.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "7.18.3", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "11.1.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "1.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "3.0.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^5.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-json-stream": { + "version": "1.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "1.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/negotiator": { + "version": "0.6.3", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "9.4.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^11.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/abbrev": { + "version": "1.1.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/gauge": { + "version": "4.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/nopt": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/npmlog": { + "version": "6.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/signal-exit": { + "version": "3.0.7", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/node-gyp/node_modules/which": { + "version": "2.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "7.2.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "5.0.0", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "6.1.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "10.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "7.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "8.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "7.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "14.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "2.0.0", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npmlog": { + "version": "7.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^4.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^5.0.0", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/once": { + "version": "1.4.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/pacote": { + "version": "15.2.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^5.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.3.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/path-is-absolute": { + "version": "1.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "1.9.2", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^9.1.1", + "minipass": "^5.0.0 || ^6.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/path-scurry/node_modules/lru-cache": { + "version": "9.1.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.0.13", + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/process": { + "version": "0.11.10", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "1.0.2", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "1.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^2.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "2.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-package-json": { + "version": "6.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "3.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/readable-stream": { + "version": "4.4.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/rimraf": { + "version": "3.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm/node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.5.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/set-blocking": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.0.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "1.7.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.1.0", + "@sigstore/tuf": "^1.0.1", + "make-fetch-happen": "^11.0.1" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.7.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.3.0", + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.13", + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/ssri": { + "version": "10.0.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/string_decoder": { + "version": "1.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.1.15", + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "1.1.7", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/wcwidth": { + "version": "1.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/npm/node_modules/which": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/wide-align": { + "version": "1.1.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrappy": { + "version": "1.0.2", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "5.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", + "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", + "dependencies": { + "array.prototype.reduce": "^1.0.5", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dependencies": { @@ -16969,6 +19933,19 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-leaflet": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.2.1.tgz", + "integrity": "sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==", + "dependencies": { + "@react-leaflet/core": "^2.1.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", @@ -21560,7 +24537,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" diff --git a/frontend/package.json b/frontend/package.json index da6b0fdb6..bfba7279f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,6 +4,9 @@ "private": true, "dependencies": { "@faker-js/faker": "^8.0.2", + "@fortawesome/fontawesome-svg-core": "^6.4.2", + "@fortawesome/free-solid-svg-icons": "^6.4.2", + "@fortawesome/react-fontawesome": "^0.2.0", "@popperjs/core": "^2.11.7", "@react-aria/ssr": "^3.6.0", "@reduxjs/toolkit": "^1.8.1", @@ -14,11 +17,13 @@ "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.1.1", "@types/faker": "^5.5.9", + "@types/leaflet": "^1.9.3", "@types/lodash": "^4.14.195", "@types/node": "^18.0.0", "@types/react": "^18.0.6", "@types/react-datepicker": "^4.11.2", "@types/react-dom": "^18.0.2", + "@types/react-leaflet": "^3.0.0", "@types/react-transition-group": "^4.4.6", "@types/redux-persist": "^4.3.1", "@types/warning": "^3.0.0", @@ -35,13 +40,16 @@ "eslint-config-airbnb-typescript": "^17.0.0", "faker": "^5.5.3", "immutable": "^4.3.0", + "install": "^0.13.0", "invariant": "^2.2.4", "jsdom": "^21.0.0", "jwt-decode": "^3.1.2", "keycloak-js": "^21.0.0", + "leaflet": "^1.9.4", "linq-to-typescript": "^11.0.0", "lodash": "^4.17.21", "make-fetch-happen": "11.0.3", + "npm": "^9.8.1", "prop-types-extra": "^1.1.1", "react": "^18.2.0", "react-bootstrap": "^2.7.4", @@ -52,6 +60,7 @@ "react-dom": "^18.2.0", "react-icons": "^4.2.0", "react-is": "^16.13.1", + "react-leaflet": "^4.2.1", "react-lifecycles-compat": "^3.0.4", "react-redux": "^8.0.1", "react-router-dom": "^6.3.0", diff --git a/frontend/src/app/common/methods.tsx b/frontend/src/app/common/methods.tsx index 6b93f33b9..96276460b 100644 --- a/frontend/src/app/common/methods.tsx +++ b/frontend/src/app/common/methods.tsx @@ -2,6 +2,8 @@ import format from "date-fns/format"; import { Coordinates } from "../types/app/coordinate-type"; import COMPLAINT_TYPES from "../types/app/complaint-types"; +type Coordinate = number[] | string[] | undefined; + export const getAvatarInitials = (input: string): string => { const tokens = input.split(" "); @@ -40,8 +42,45 @@ export const formatDateTime = (input: string | undefined): string => { return format(Date.parse(input), "yyyy-MM-dd HH:mm"); }; +// Used to retrieve the coordinates in the decimal format +export const parseDecimalDegreesCoordinates = ( + coordinates: Coordinate +): { lat: number; lng: number } => { + if (!coordinates) { + return { lat: 0, lng: 0 }; + } + + return { lat: +coordinates[0], lng: +coordinates[1] }; +}; + +// given coordinates, return true if within BC or false if not within BC +export const isWithinBC = ( + coordinates: Coordinate +): boolean => { + const bcBoundaries = { + minLatitude: 48.2513, + maxLatitude: 60.0, + minLongitude: -139.0596, + maxLongitude: -114.0337, + }; + + if (!coordinates) { + return false; + } + + const latitude = +coordinates[0]; + const longitude = +coordinates[1]; + + return ( + latitude >= bcBoundaries.minLatitude && + latitude <= bcBoundaries.maxLatitude && + longitude >= bcBoundaries.minLongitude && + longitude <= bcBoundaries.maxLongitude + ); +}; + export const parseCoordinates = ( - coordinates: number[] | string[] | undefined, + coordinates: Coordinate, coordinateType: Coordinates ): number | string => { if (!coordinates) { @@ -65,12 +104,10 @@ export const getComplaintTypeFromUrl = (): number => { }; export const renderCoordinates = ( - coordinates: number[] | string[] | undefined, + coordinates: Coordinate, coordinateType: Coordinates ): JSX.Element => { const result = parseCoordinates(coordinates, coordinateType); - return result === 0 ? <>{'Not Provided'} : <>{result}; + return result === 0 ? <>{"Not Provided"} : <>{result}; }; - - diff --git a/frontend/src/app/components/containers/complaints/complaint-details.tsx b/frontend/src/app/components/containers/complaints/complaint-details.tsx index 182837b33..fd8be6ce3 100644 --- a/frontend/src/app/components/containers/complaints/complaint-details.tsx +++ b/frontend/src/app/components/containers/complaints/complaint-details.tsx @@ -15,6 +15,7 @@ import { Button } from "react-bootstrap"; import { ComplaintDetailsEdit } from "./details/complaint-details-edit"; import { openModal } from "../../../store/reducers/app"; import { CancelConfirm } from "../../../types/modal/modal-types"; +import { ComplaintLocation } from "./details/complaint-location"; type ComplaintParams = { id: string; @@ -87,6 +88,9 @@ export const ComplaintDetails: FC = () => { { readOnly && } + { readOnly && + + } { readOnly && } diff --git a/frontend/src/app/components/containers/complaints/details/call-details.tsx b/frontend/src/app/components/containers/complaints/details/call-details.tsx index dfdcfe58d..3ad6cec66 100644 --- a/frontend/src/app/components/containers/complaints/details/call-details.tsx +++ b/frontend/src/app/components/containers/complaints/details/call-details.tsx @@ -116,12 +116,12 @@ export const CallDetails: FC = ({
X Coordinate
-
+
{renderCoordinates(coordinates, Coordinates.Latitude)}
Y Coordinate
-
+
{renderCoordinates(coordinates, Coordinates.Longitude)}
diff --git a/frontend/src/app/components/containers/complaints/details/complaint-details-edit.tsx b/frontend/src/app/components/containers/complaints/details/complaint-details-edit.tsx index 91bff26a3..870907fb0 100644 --- a/frontend/src/app/components/containers/complaints/details/complaint-details-edit.tsx +++ b/frontend/src/app/components/containers/complaints/details/complaint-details-edit.tsx @@ -31,6 +31,7 @@ import { DropdownOption } from "../../../../types/code-tables/option"; import COMPLAINT_TYPES from "../../../../types/app/complaint-types"; import { ComplaintSuspectWitness } from "../../../../types/complaints/details/complaint-suspect-witness-details"; import { selectOfficersByZone } from "../../../../store/reducers/officer"; +import { ComplaintLocation } from "./complaint-location"; interface ComplaintHeaderProps { complaintType: string; @@ -493,6 +494,7 @@ export const ComplaintDetailsEdit: FC = ({
+ {/* edit caller info block */}
Caller Information
diff --git a/frontend/src/app/components/containers/complaints/details/complaint-location.tsx b/frontend/src/app/components/containers/complaints/details/complaint-location.tsx new file mode 100644 index 000000000..b6953bf57 --- /dev/null +++ b/frontend/src/app/components/containers/complaints/details/complaint-location.tsx @@ -0,0 +1,37 @@ +import { FC } from "react"; +import { useAppSelector } from "../../../../hooks/hooks"; +import { selectComplaintDeails } from "../../../../store/reducers/complaints"; +import LeafletMapWithPoint from "../../../mapping/leaflet-map-with-point"; +import { ComplaintDetails } from "../../../../types/complaints/details/complaint-details"; +import { + parseDecimalDegreesCoordinates, +} from "../../../../common/methods"; + +type Props = { + complaintType: string; + draggable: boolean; +}; + +/** + * Component that displays a map with a marker representing the complaint location + * + */ +export const ComplaintLocation: FC = ({ complaintType, draggable }) => { + const { coordinates } = useAppSelector( + selectComplaintDeails(complaintType) + ) as ComplaintDetails; + + const decimalDegreesCoordinates = parseDecimalDegreesCoordinates(coordinates); + + return ( +
+
Complaint Location
+
+ +
+
+ ); +}; diff --git a/frontend/src/app/components/mapping/leaflet-map-with-point.tsx b/frontend/src/app/components/mapping/leaflet-map-with-point.tsx new file mode 100644 index 000000000..c23209042 --- /dev/null +++ b/frontend/src/app/components/mapping/leaflet-map-with-point.tsx @@ -0,0 +1,78 @@ +import { FC, useEffect } from "react"; +import { MapContainer, TileLayer, Marker, useMap } from "react-leaflet"; +import "leaflet/dist/leaflet.css"; // Import Leaflet CSS +import "@fortawesome/fontawesome-svg-core/styles.css"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import ReactDOMServer from "react-dom/server"; +import { faMapMarkerAlt } from "@fortawesome/free-solid-svg-icons"; + +import Leaflet from "leaflet"; + +type Props = { + coordinates?: { lat: number; lng: number }; + draggable: boolean; +}; + +/** + * Renders a map with a marker at the supplied location + * + */ +const LeafletMapWithPoint: FC = ({ coordinates, draggable }) => { + // the derived lat long pair. + // If a coordinate is supplied, then the latLng is set to the supplied coordinates. + // If coordinates aren't supplied, then use the BC Geocoder to determine the latLng based on an address (if supplied), or + // the community. Every complaint will have a community, so theoretically, there will always be a latLng that can be derived. + let latLng: { lat: number; lng: number }; + + if (coordinates) { + latLng = coordinates; + } else { + // handle other methods of determining coordinates + // for now just return 0,0 + latLng = { lat: 0, lng: 0 }; + } + + const iconHTML = ReactDOMServer.renderToString( + + ); + const customMarkerIcon = new Leaflet.DivIcon({ + html: iconHTML, + className: "map-marker", + iconSize: [40, 0], // Adjust icon size as needed + iconAnchor: [20, 40], // Adjust icon anchor point + }); + + // recenter the map when the center value is updated + const Centerer = () => { + const map = useMap(); + + useEffect(() => { + if (latLng) { + map.setView(latLng); + } + }, [map]); + + return null; + }; + + return ( + + + + + + + ); +}; + +export default LeafletMapWithPoint; diff --git a/frontend/src/assets/images/map/layers-2x.png b/frontend/src/assets/images/map/layers-2x.png new file mode 100644 index 000000000..200c333dc Binary files /dev/null and b/frontend/src/assets/images/map/layers-2x.png differ diff --git a/frontend/src/assets/images/map/layers.png b/frontend/src/assets/images/map/layers.png new file mode 100644 index 000000000..1a72e5784 Binary files /dev/null and b/frontend/src/assets/images/map/layers.png differ diff --git a/frontend/src/assets/images/map/marker-icon-2x.png b/frontend/src/assets/images/map/marker-icon-2x.png new file mode 100644 index 000000000..88f9e5018 Binary files /dev/null and b/frontend/src/assets/images/map/marker-icon-2x.png differ diff --git a/frontend/src/assets/images/map/marker-icon.png b/frontend/src/assets/images/map/marker-icon.png new file mode 100644 index 000000000..950edf246 Binary files /dev/null and b/frontend/src/assets/images/map/marker-icon.png differ diff --git a/frontend/src/assets/images/map/marker-shadow.png b/frontend/src/assets/images/map/marker-shadow.png new file mode 100644 index 000000000..9fd297953 Binary files /dev/null and b/frontend/src/assets/images/map/marker-shadow.png differ diff --git a/frontend/src/assets/sass/app.scss b/frontend/src/assets/sass/app.scss index ed9899594..dde077c18 100644 --- a/frontend/src/assets/sass/app.scss +++ b/frontend/src/assets/sass/app.scss @@ -21,4 +21,5 @@ @import "../../../node_modules/bootstrap-icons/font/bootstrap-icons.scss"; @import "./complaint.scss"; //-- dont move this unless you want to fix broken styles -@import "./zone-at-a-glance.scss"; \ No newline at end of file +@import "./zone-at-a-glance.scss"; +@import "./maps.scss"; \ No newline at end of file diff --git a/frontend/src/assets/sass/complaint.scss b/frontend/src/assets/sass/complaint.scss index 327e65add..21f258972 100644 --- a/frontend/src/assets/sass/complaint.scss +++ b/frontend/src/assets/sass/complaint.scss @@ -285,6 +285,24 @@ } } +.comp-complaint-details-location-block { + margin-left: 24px; + margin-right: 24px; + + h6 { + padding-top: 0px; + font-weight: 700; + margin-bottom: 0px; + } + + .comp-complaint-location { + margin-top: 24px; + margin-bottom: 24px; + } + + +} + .comp-complaint-header-edit-block { margin: 24px 24px; padding: 24px; diff --git a/frontend/src/assets/sass/maps.scss b/frontend/src/assets/sass/maps.scss new file mode 100644 index 000000000..532ec73bb --- /dev/null +++ b/frontend/src/assets/sass/maps.scss @@ -0,0 +1,6 @@ +.map-marker { + color: red; + font-size: 40px; + text-align: center; /* Horizontally center the text (icon) */ + line-height: 20px; /* Vertically center the text (icon) */ +} \ No newline at end of file