diff --git a/.env.example b/.env.example index 2cd534f9c..67e32ec23 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: 2021 - 2022 Netherlands eScience Center # SPDX-FileCopyrightText: 2021 - 2022 dv4all +# SPDX-FileCopyrightText: 2022 Helmholtz Centre for Environmental Research (UFZ) # # SPDX-License-Identifier: CC-BY-4.0 # @@ -25,6 +26,10 @@ COMPOSE_PROJECT_NAME="rsd" # ---- PUBLIC ENV VARIABLES ------------- # postgresql +# consumed by services: backend +POSTGRES_DB_HOST=database +# consumed by services: backend +POSTGRES_DB_HOST_PORT=5432 # consumed by services: database, backend POSTGRES_DB=rsd-db # consumed by services: database diff --git a/CITATION.cff b/CITATION.cff index 4d9cda253..2a3e1e212 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -75,5 +75,5 @@ keywords: - Software Impact - Software Reuse license: Apache-2.0 -version: v1.11.1 -date-released: '2022-11-18' +version: v1.12.0 +date-released: '2022-11-30' diff --git a/data-generation/main.js b/data-generation/main.js index d84231512..627d757fc 100644 --- a/data-generation/main.js +++ b/data-generation/main.js @@ -261,7 +261,9 @@ function generateSoftwareForSoftware(ids) { return result; } -function generateProjects(amount=50) { +async function generateProjects(amount=50) { + const imageIds = await downloadAndGetImages(faker.image.cats, amount); + const result = []; for (let index = 0; index < amount; index++) { @@ -278,6 +280,7 @@ function generateProjects(amount=50) { grant_id: faker.helpers.replaceSymbols('******'), image_caption: faker.animal.cat(), image_contain: !!faker.helpers.maybe(() => true, {probability: 0.5}), + image_id: imageIds[index] ?? null, is_published: !!faker.helpers.maybe(() => true, {probability: 0.8}), }); } @@ -286,7 +289,7 @@ function generateProjects(amount=50) { } async function generateContributors(ids, amount=100) { - const base64Images = await downloadImagesAsBase64(faker.image.avatar, amount); + const imageIds = await downloadAndGetImages(faker.image.avatar, amount); const result = []; @@ -300,8 +303,7 @@ async function generateContributors(ids, amount=100) { affiliation: faker.company.name(), role: faker.name.jobTitle(), orcid: faker.helpers.replaceSymbolWithNumber('####-####-####-####'), - avatar_data: base64Images[index], - avatar_mime_type: 'image/jpeg', + avatar_id: imageIds[index] ?? null, }); } @@ -317,23 +319,6 @@ async function generateTeamMembers(ids, amount=100) { return result; } -async function generateImagesForProjects(ids) { - const base64Images = await downloadImagesAsBase64(faker.image.cats, ids.length); - - const result = []; - - for (let index = 0; index < ids.length; index++) { - if (base64Images[index] === null) continue; - result.push({ - project: ids[index], - data: base64Images[index], - mime_type: 'image/jpeg', - }); - } - - return result; -} - function generateUrlsForProjects(ids) { const result = []; @@ -352,7 +337,9 @@ function generateUrlsForProjects(ids) { return result; } -function generateOrganisations(amount=50) { +async function generateOrganisations(amount=50) { + const imageIds = await downloadAndGetImages(faker.image.business, amount); + const result = []; for (let index = 0; index < amount; index++) { @@ -367,23 +354,7 @@ function generateOrganisations(amount=50) { ror_id: faker.helpers.replaceSymbols('https://ror.org/********'), website: faker.internet.url(), is_tenant: !!faker.helpers.maybe(() => true, {probability: 0.3}), - }); - } - - return result; -} - -async function generateLogosForOrganisations(ids) { - const base64Images = await downloadImagesAsBase64(faker.image.business, ids.length); - - const result = []; - - for (let index = 0; index < ids.length; index++) { - if (base64Images[index] === null) continue; - result.push({ - organisation: ids[index], - data: base64Images[index], - mime_type: 'image/jpeg', + logo_id: imageIds[index] ?? null, }); } @@ -442,7 +413,11 @@ function createJWT() { } const token = createJWT(); -const headers = {'Content-Type': 'application/json', 'Authorization': 'bearer ' + token, 'Prefer': 'return=representation'} +const headers = { + 'Content-Type': 'application/json', + 'Authorization': 'bearer ' + token, + 'Prefer': 'return=representation,resolution=ignore-duplicates' + } const backendUrl = process.env.POSTGREST_URL || 'http://localhost/api/v1'; async function postToBackend(endpoint, body) { @@ -461,12 +436,13 @@ async function getFromBackend(endpoint) { return response; } -async function downloadImagesAsBase64(urlGenerator, amount) { - const imagePromises = []; +// returns the IDs of the images after they have been posted to the database +async function downloadAndGetImages(urlGenerator, amount) { + const imageAsBase64Promises = []; const timeOuts = []; for (let index = 0; index < amount; index++) { const url = urlGenerator(); - imagePromises.push( + imageAsBase64Promises.push( Promise.race([ fetch(url) .then(resp => {clearTimeout(timeOuts[index]); return resp.arrayBuffer()}) @@ -477,7 +453,16 @@ async function downloadImagesAsBase64(urlGenerator, amount) { ]) ); } - return await Promise.all(imagePromises); + const imagesAsBase64 = await Promise.all(imageAsBase64Promises); + + const imagesWithoutNulls = imagesAsBase64 + .filter(img => img !== null) + .map(base64 => {return {data: base64, mime_type: 'image/jpeg'}}); + + const resp = await postToBackend('/image?select=id', imagesWithoutNulls); + const idsAsObjects = await resp.json(); + const ids = idsAsObjects.map(idAsObject => idAsObject.id); + return ids } let idsMentions, idsKeywords, idsResearchDomains; @@ -508,12 +493,11 @@ const softwarePromise = postToBackend('/software', generateSofware()) postToBackend('/mention_for_software', generateMentionsForEntity(idsSoftware, idsMentions, 'software')); postToBackend('/software_for_software', generateSoftwareForSoftware(idsSoftware)); }); -const projectPromise = postToBackend('/project', generateProjects()) +const projectPromise = postToBackend('/project', await generateProjects()) .then(resp => resp.json()) .then(async pjArray => { idsProjects = pjArray.map(sw => sw['id']); postToBackend('/team_member', await generateTeamMembers(idsProjects)); - postToBackend('/image_for_project', await generateImagesForProjects(idsProjects)); postToBackend('/url_for_project', generateUrlsForProjects(idsProjects)); postToBackend('/keyword_for_project', generateKeywordsForEntity(idsProjects, idsKeywords, 'project')); postToBackend('/output_for_project', generateMentionsForEntity(idsProjects, idsMentions, 'project')); @@ -521,11 +505,10 @@ const projectPromise = postToBackend('/project', generateProjects()) postToBackend('/research_domain_for_project', generateResearchDomainsForProjects(idsProjects, idsResearchDomains)); postToBackend('/project_for_project', generateSoftwareForSoftware(idsProjects)); }); -const organisationPromise = postToBackend('/organisation', generateOrganisations()) +const organisationPromise = postToBackend('/organisation', await generateOrganisations()) .then(resp => resp.json()) .then(async orgArray => { idsOrganisations = orgArray.map(org => org['id']); - postToBackend('/logo_for_organisation', await generateLogosForOrganisations(idsOrganisations)); }); await postToBackend('/meta_pages', generateMetaPages()).then(() => console.log('meta pages done')); diff --git a/database/002-create-image-table.sql b/database/002-create-image-table.sql new file mode 100644 index 000000000..69f0aeec9 --- /dev/null +++ b/database/002-create-image-table.sql @@ -0,0 +1,74 @@ +-- SPDX-FileCopyrightText: 2022 Dusan Mijatovic (dv4all) +-- SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) +-- SPDX-FileCopyrightText: 2022 Netherlands eScience Center +-- SPDX-FileCopyrightText: 2022 dv4all +-- +-- SPDX-License-Identifier: Apache-2.0 + +-- create extension pgcrypto to encrypt base64 content +CREATE EXTENSION IF NOT EXISTS pgcrypto; + +CREATE TABLE image ( + id VARCHAR(40) PRIMARY KEY, + data VARCHAR(2750000) NOT NULL, + mime_type VARCHAR(100) NOT NULL, + created_at TIMESTAMPTZ NOT NULL +); + +CREATE FUNCTION sanitise_insert_image() RETURNS TRIGGER LANGUAGE plpgsql AS +$$ +BEGIN +-- create SHA-1 id based on provided data content + NEW.id = ENCODE(DIGEST(NEW.data, 'sha1'), 'hex'); + NEW.created_at = LOCALTIMESTAMP; + return NEW; +END +$$; + +CREATE TRIGGER sanitise_insert_image BEFORE INSERT ON image FOR EACH ROW EXECUTE PROCEDURE sanitise_insert_image(); + +CREATE FUNCTION sanitise_update_image() RETURNS TRIGGER LANGUAGE plpgsql AS +$$ +BEGIN +-- create SHA-1 id based on provided data content + NEW.id = ENCODE(DIGEST(NEW.data, 'sha1'), 'hex'); + return NEW; +END +$$; + +CREATE TRIGGER sanitise_update_image BEFORE UPDATE ON image FOR EACH ROW EXECUTE PROCEDURE sanitise_update_image(); + + +-- ---------------------------------------- +-- RPC to get image by id => sha-1 of data +-- ---------------------------------------- + +CREATE FUNCTION get_image(uid VARCHAR(40)) RETURNS BYTEA STABLE LANGUAGE plpgsql AS +$$ +DECLARE headers TEXT; +DECLARE blob BYTEA; + +BEGIN + SELECT format( + '[{"Content-Type": "%s"},' + '{"Content-Disposition": "inline; filename=\"%s\""},' + '{"Cache-Control": "max-age=259200"}]', + mime_type, + uid) + FROM image WHERE id = uid INTO headers; + + PERFORM set_config('response.headers', headers, TRUE); + + SELECT decode(image.data, 'base64') FROM image WHERE id = uid INTO blob; + + IF FOUND + THEN RETURN(blob); + ELSE RAISE SQLSTATE 'PT404' + USING + message = 'NOT FOUND', + detail = 'File not found', + hint = format('%s seems to be an invalid file id', image_id); + END IF; +END +$$; + diff --git a/database/002-create-software-table.sql b/database/003-create-software-table.sql similarity index 100% rename from database/002-create-software-table.sql rename to database/003-create-software-table.sql diff --git a/database/003-create-relations-for-software.sql b/database/004-create-relations-for-software.sql similarity index 81% rename from database/003-create-relations-for-software.sql rename to database/004-create-relations-for-software.sql index 6dbb1dcb5..2f83eece6 100644 --- a/database/003-create-relations-for-software.sql +++ b/database/004-create-relations-for-software.sql @@ -75,8 +75,7 @@ CREATE TABLE contributor ( role VARCHAR(200), orcid VARCHAR(19) CHECK (orcid ~ '^\d{4}-\d{4}-\d{4}-\d{3}[0-9X]$'), position INTEGER, - avatar_data VARCHAR(2750000), - avatar_mime_type VARCHAR(100), + avatar_id VARCHAR(40) REFERENCES image(id), created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL ); @@ -106,37 +105,6 @@ $$; CREATE TRIGGER sanitise_update_contributor BEFORE UPDATE ON contributor FOR EACH ROW EXECUTE PROCEDURE sanitise_update_contributor(); - -CREATE FUNCTION get_contributor_image(id UUID) RETURNS BYTEA STABLE LANGUAGE plpgsql AS -$$ -DECLARE headers TEXT; -DECLARE blob BYTEA; - -BEGIN - SELECT format( - '[{"Content-Type": "%s"},' - '{"Content-Disposition": "inline; filename=\"%s\""},' - '{"Cache-Control": "max-age=259200"}]', - contributor.avatar_mime_type, - contributor.id) - FROM contributor WHERE contributor.id = get_contributor_image.id INTO headers; - - PERFORM set_config('response.headers', headers, TRUE); - - SELECT decode(contributor.avatar_data, 'base64') FROM contributor WHERE contributor.id = get_contributor_image.id INTO blob; - - IF FOUND - THEN RETURN(blob); - ELSE RAISE SQLSTATE 'PT404' - USING - message = 'NOT FOUND', - detail = 'File not found', - hint = format('%s seems to be an invalid file id', get_contributor_image.id); - END IF; -END -$$; - - CREATE TABLE testimonial ( id UUID DEFAULT gen_random_uuid() PRIMARY KEY, software UUID REFERENCES software (id) NOT NULL, diff --git a/database/004-create-project-table.sql b/database/005-create-project-table.sql similarity index 70% rename from database/004-create-project-table.sql rename to database/005-create-project-table.sql index 01f2b82ce..68f93b754 100644 --- a/database/004-create-project-table.sql +++ b/database/005-create-project-table.sql @@ -16,6 +16,7 @@ CREATE TABLE project ( grant_id VARCHAR(50), image_caption VARCHAR(500), image_contain BOOLEAN DEFAULT FALSE NOT NULL, + image_id VARCHAR(40) REFERENCES image(id), is_published BOOLEAN DEFAULT FALSE NOT NULL, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL @@ -80,42 +81,3 @@ END $$; CREATE TRIGGER sanitise_update_url_for_project BEFORE UPDATE ON url_for_project FOR EACH ROW EXECUTE PROCEDURE sanitise_update_url_for_project(); - - -CREATE TABLE image_for_project ( - project UUID REFERENCES project (id) PRIMARY KEY, - data VARCHAR(2750000) NOT NULL, - mime_type VARCHAR(100) NOT NULL -); - - -CREATE FUNCTION get_project_image(id UUID) RETURNS BYTEA STABLE LANGUAGE plpgsql AS -$$ -DECLARE headers TEXT; -DECLARE blob BYTEA; -DECLARE project_slug VARCHAR; - -BEGIN - SELECT slug FROM project WHERE project.id = get_project_image.id INTO project_slug; - SELECT format( - '[{"Content-Type": "%s"},' - '{"Content-Disposition": "inline; filename=\"%s\""},' - '{"Cache-Control": "max-age=259200"}]', - mime_type, - project_slug) - FROM image_for_project WHERE project = id INTO headers; - - PERFORM set_config('response.headers', headers, TRUE); - - SELECT decode(image_for_project.data, 'base64') FROM image_for_project WHERE image_for_project.project = get_project_image.id INTO blob; - - IF FOUND - THEN RETURN(blob); - ELSE RAISE SQLSTATE 'PT404' - USING - message = 'NOT FOUND', - detail = 'File not found', - hint = format('%s seems to be an invalid file id', get_project_image.id); - END IF; -END -$$; diff --git a/database/005-create-relations-for-projects.sql b/database/006-create-relations-for-projects.sql similarity index 62% rename from database/005-create-relations-for-projects.sql rename to database/006-create-relations-for-projects.sql index a89c731ff..0ff952965 100644 --- a/database/005-create-relations-for-projects.sql +++ b/database/006-create-relations-for-projects.sql @@ -16,8 +16,7 @@ CREATE TABLE team_member ( role VARCHAR(200), orcid VARCHAR(19) CHECK (orcid ~ '^\d{4}-\d{4}-\d{4}-\d{3}[0-9X]$'), position INTEGER, - avatar_data VARCHAR(2750000), - avatar_mime_type VARCHAR(100), + avatar_id VARCHAR(40) REFERENCES image(id), created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL ); @@ -46,33 +45,3 @@ END $$; CREATE TRIGGER sanitise_update_team_member BEFORE UPDATE ON team_member FOR EACH ROW EXECUTE PROCEDURE sanitise_update_team_member(); - - -CREATE FUNCTION get_team_member_image(id UUID) RETURNS BYTEA STABLE LANGUAGE plpgsql AS -$$ -DECLARE headers TEXT; -DECLARE blob BYTEA; - -BEGIN - SELECT format( - '[{"Content-Type": "%s"},' - '{"Content-Disposition": "inline; filename=\"%s\""},' - '{"Cache-Control": "max-age=259200"}]', - team_member.avatar_mime_type, - team_member.id) - FROM team_member WHERE team_member.id = get_team_member_image.id INTO headers; - - PERFORM set_config('response.headers', headers, TRUE); - - SELECT decode(team_member.avatar_data, 'base64') FROM team_member WHERE team_member.id = get_team_member_image.id INTO blob; - - IF FOUND - THEN RETURN(blob); - ELSE RAISE SQLSTATE 'PT404' - USING - message = 'NOT FOUND', - detail = 'File not found', - hint = format('%s seems to be an invalid file id', get_team_member_image.id); - END IF; -END -$$; diff --git a/database/006-create-keyword.sql b/database/007-create-keyword.sql similarity index 100% rename from database/006-create-keyword.sql rename to database/007-create-keyword.sql diff --git a/database/007-create-research-domain.sql b/database/008-create-research-domain.sql similarity index 100% rename from database/007-create-research-domain.sql rename to database/008-create-research-domain.sql diff --git a/database/008-create-mention-table.sql b/database/009-create-mention-table.sql similarity index 100% rename from database/008-create-mention-table.sql rename to database/009-create-mention-table.sql diff --git a/database/009-create-release-table.sql b/database/010-create-release-table.sql similarity index 100% rename from database/009-create-release-table.sql rename to database/010-create-release-table.sql diff --git a/database/010-create-account-table.sql b/database/011-create-account-table.sql similarity index 100% rename from database/010-create-account-table.sql rename to database/011-create-account-table.sql diff --git a/database/011-create-organisation-table.sql b/database/012-create-organisation-table.sql similarity index 84% rename from database/011-create-organisation-table.sql rename to database/012-create-organisation-table.sql index d85486b08..10130eb9d 100644 --- a/database/011-create-organisation-table.sql +++ b/database/012-create-organisation-table.sql @@ -12,11 +12,10 @@ CREATE TABLE organisation ( slug VARCHAR(200) NOT NULL CHECK (slug ~ '^[a-z0-9]+(-[a-z0-9]+)*$'), name VARCHAR(200) NOT NULL, description VARCHAR(10000), - -- location VARCHAR(200), - -- type VARCHAR(100), ror_id VARCHAR(100) UNIQUE, website VARCHAR(200) UNIQUE, is_tenant BOOLEAN DEFAULT FALSE NOT NULL, + logo_id VARCHAR(40) REFERENCES image(id), created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL, UNIQUE (slug, parent) @@ -142,43 +141,6 @@ END $$; -CREATE TABLE logo_for_organisation ( - organisation UUID references organisation(id) PRIMARY KEY, - data VARCHAR(2750000) NOT NULL, - mime_type VARCHAR(100) NOT NULL, - created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP NOT NULL -); - - -CREATE FUNCTION get_logo(id UUID) RETURNS BYTEA STABLE LANGUAGE plpgsql AS -$$ -DECLARE headers TEXT; -DECLARE blob BYTEA; - -BEGIN - SELECT format( - '[{"Content-Type": "%s"},' - '{"Content-Disposition": "inline; filename=\"%s\""},' - '{"Cache-Control": "max-age=259200"}]', - logo_for_organisation.mime_type, - logo_for_organisation.organisation) - FROM logo_for_organisation WHERE logo_for_organisation.organisation = get_logo.id INTO headers; - - PERFORM set_config('response.headers', headers, TRUE); - - SELECT decode(logo_for_organisation.data, 'base64') FROM logo_for_organisation WHERE logo_for_organisation.organisation = get_logo.id INTO blob; - - IF FOUND - THEN RETURN(blob); - ELSE RAISE SQLSTATE 'PT404' - USING - message = 'NOT FOUND', - detail = 'File not found', - hint = format('%s seems to be an invalid file id', get_logo.id); - END IF; -END -$$; - -- ORGANISATION route / path for all organisations -- we combine slugs of all parent organisation into route CREATE FUNCTION organisation_route( diff --git a/database/012-inter-relation-tables.sql b/database/013-inter-relation-tables.sql similarity index 100% rename from database/012-inter-relation-tables.sql rename to database/013-inter-relation-tables.sql diff --git a/database/020-row-level-security.sql b/database/020-row-level-security.sql index dd35bed02..13b23a1eb 100644 --- a/database/020-row-level-security.sql +++ b/database/020-row-level-security.sql @@ -146,6 +146,21 @@ CREATE POLICY admin_all_rights ON invite_maintainer_for_organisation TO rsd_admi WITH CHECK (TRUE); +-- image +ALTER TABLE image ENABLE ROW LEVEL SECURITY; + +CREATE POLICY anyone_can_read ON image FOR SELECT TO web_anon, rsd_user + USING (TRUE); + +CREATE POLICY rsd_user_all_rights ON image TO rsd_user + USING (TRUE) + WITH CHECK (TRUE); + +CREATE POLICY admin_all_rights ON image TO rsd_admin + USING (TRUE) + WITH CHECK (TRUE); + + -- software ALTER TABLE software ENABLE ROW LEVEL SECURITY; @@ -307,21 +322,6 @@ CREATE POLICY admin_all_rights ON url_for_project TO rsd_admin USING (TRUE) WITH CHECK (TRUE); - -ALTER TABLE image_for_project ENABLE ROW LEVEL SECURITY; - -CREATE POLICY anyone_can_read ON image_for_project FOR SELECT TO web_anon, rsd_user - USING (project IN (SELECT id FROM project)); - -CREATE POLICY maintainer_all_rights ON image_for_project TO rsd_user - USING (project IN (SELECT * FROM projects_of_current_maintainer())) - WITH CHECK (project IN (SELECT * FROM projects_of_current_maintainer())); - -CREATE POLICY admin_all_rights ON image_for_project TO rsd_admin - USING (TRUE) - WITH CHECK (TRUE); - - -- project relations ALTER TABLE team_member ENABLE ROW LEVEL SECURITY; @@ -516,24 +516,6 @@ CREATE POLICY admin_all_rights ON organisation TO rsd_admin USING (TRUE) WITH CHECK (TRUE); - -ALTER TABLE logo_for_organisation ENABLE ROW LEVEL SECURITY; - -CREATE POLICY anyone_can_read ON logo_for_organisation FOR SELECT TO web_anon, rsd_user - USING (organisation IN (SELECT id FROM organisation)); - -CREATE POLICY maintainer_insert_non_tenant ON logo_for_organisation FOR INSERT TO rsd_user - WITH CHECK (NOT (SELECT is_tenant FROM organisation o WHERE o.id = logo_for_organisation.organisation)); - -CREATE POLICY maintainer_all_rights ON logo_for_organisation TO rsd_user - USING (organisation IN (SELECT * FROM organisations_of_current_maintainer())) - WITH CHECK (organisation IN (SELECT * FROM organisations_of_current_maintainer())); - -CREATE POLICY admin_all_rights ON logo_for_organisation TO rsd_admin - USING (TRUE) - WITH CHECK (TRUE); - - -- inter relations ALTER TABLE software_for_software ENABLE ROW LEVEL SECURITY; diff --git a/database/100-create-api-views.sql b/database/100-create-api-views.sql index 80f872352..8053a4a35 100644 --- a/database/100-create-api-views.sql +++ b/database/100-create-api-views.sql @@ -224,11 +224,26 @@ END $$; -- UNIQUE contributor display_names -CREATE OR REPLACE FUNCTION unique_contributors() RETURNS TABLE (display_name TEXT, affiliation VARCHAR, orcid VARCHAR, given_names VARCHAR, family_names VARCHAR, email_address VARCHAR, avatar_mime_type VARCHAR) LANGUAGE plpgsql STABLE AS +CREATE OR REPLACE FUNCTION unique_contributors() RETURNS TABLE ( + display_name TEXT, + affiliation VARCHAR, + orcid VARCHAR, + given_names VARCHAR, + family_names VARCHAR, + email_address VARCHAR, + avatar_id VARCHAR +) LANGUAGE plpgsql STABLE AS $$ BEGIN - RETURN QUERY SELECT DISTINCT - (CONCAT(c.given_names,' ',c.family_names)) AS display_name, c.affiliation, c.orcid, c.given_names, c.family_names, c.email_address, c.avatar_mime_type + RETURN QUERY + SELECT DISTINCT + (CONCAT(c.given_names,' ',c.family_names)) AS display_name, + c.affiliation, + c.orcid, + c.given_names, + c.family_names, + c.email_address, + c.avatar_id FROM contributor c ORDER BY @@ -247,7 +262,7 @@ CREATE FUNCTION organisations_of_software(software_id UUID) RETURNS TABLE ( is_tenant BOOLEAN, website VARCHAR, rsd_path VARCHAR, - logo_id UUID, + logo_id VARCHAR, status relation_status, "position" INTEGER, software UUID @@ -264,7 +279,7 @@ BEGIN organisation.is_tenant, organisation.website, organisation_route.rsd_path, - logo_for_organisation.organisation AS logo_id, + organisation.logo_id, software_for_organisation.status, software_for_organisation.position, software.id AS software @@ -276,8 +291,6 @@ BEGIN organisation ON software_for_organisation.organisation = organisation.id LEFT JOIN organisation_route(organisation.id) ON organisation_route.organisation = organisation.id - LEFT JOIN - logo_for_organisation ON logo_for_organisation.organisation = organisation.id WHERE software.id = software_id ; @@ -390,7 +403,7 @@ CREATE FUNCTION organisations_overview(public BOOLEAN DEFAULT TRUE) RETURNS TABL website VARCHAR, is_tenant BOOLEAN, rsd_path VARCHAR, - logo_id UUID, + logo_id VARCHAR, software_cnt BIGINT, project_cnt BIGINT, children_cnt BIGINT, @@ -409,7 +422,7 @@ BEGIN organisation.website, organisation.is_tenant, organisation_route.rsd_path, - logo_for_organisation.organisation AS logo_id, + organisation.logo_id, software_count_by_organisation.software_cnt, project_count_by_organisation.project_cnt, children_count_by_organisation.children_cnt, @@ -427,8 +440,7 @@ BEGIN project_count_by_organisation(public) ON project_count_by_organisation.organisation = organisation.id LEFT JOIN children_count_by_organisation() ON children_count_by_organisation.parent = organisation.id - LEFT JOIN - logo_for_organisation ON logo_for_organisation.organisation = organisation.id; + ; END $$; @@ -490,7 +502,7 @@ CREATE FUNCTION projects_by_organisation(organisation_id UUID) RETURNS TABLE ( is_published BOOLEAN, image_contain BOOLEAN, is_featured BOOLEAN, - image_id UUID, + image_id VARCHAR, organisation UUID, status relation_status, keywords citext[] @@ -513,14 +525,12 @@ BEGIN project.is_published, project.image_contain, project_for_organisation.is_featured, - image_for_project.project AS image_id, + project.image_id, project_for_organisation.organisation, project_for_organisation.status, keyword_filter_for_project.keywords FROM project - LEFT JOIN - image_for_project ON project.id = image_for_project.project LEFT JOIN project_for_organisation ON project.id = project_for_organisation.project LEFT JOIN @@ -542,7 +552,7 @@ CREATE FUNCTION organisations_of_project(project_id UUID) RETURNS TABLE ( is_tenant BOOLEAN, website VARCHAR, rsd_path VARCHAR, - logo_id UUID, + logo_id VARCHAR, status relation_status, role organisation_role, "position" INTEGER, @@ -561,7 +571,7 @@ BEGIN organisation.is_tenant, organisation.website, organisation_route.rsd_path, - logo_for_organisation.organisation AS logo_id, + organisation.logo_id, project_for_organisation.status, project_for_organisation.role, project_for_organisation.position, @@ -575,8 +585,6 @@ BEGIN organisation ON project_for_organisation.organisation = organisation.id LEFT JOIN organisation_route(organisation.id) ON organisation_route.organisation = organisation.id - LEFT JOIN - logo_for_organisation ON logo_for_organisation.organisation = organisation.id WHERE project.id = project_id ; @@ -598,7 +606,7 @@ CREATE FUNCTION related_projects_for_project(origin_id UUID) RETURNS TABLE ( is_published BOOLEAN, image_contain BOOLEAN, status relation_status, - image_id UUID + image_id VARCHAR ) LANGUAGE plpgsql STABLE AS $$ BEGIN @@ -619,11 +627,9 @@ BEGIN project.is_published, project.image_contain, project_for_project.status, - image_for_project.project AS image_id + project.image_id FROM project - LEFT JOIN - image_for_project ON image_for_project.project = project.id INNER JOIN project_for_project ON project.id = project_for_project.relation WHERE @@ -647,7 +653,7 @@ CREATE FUNCTION related_projects_for_software(software_id UUID) RETURNS TABLE ( is_published BOOLEAN, image_contain BOOLEAN, status relation_status, - image_id UUID + image_id VARCHAR ) LANGUAGE plpgsql STABLE AS $$ BEGIN @@ -668,11 +674,9 @@ BEGIN project.is_published, project.image_contain, software_for_project.status, - image_for_project.project AS image_id + project.image_id FROM project - LEFT JOIN - image_for_project ON image_for_project.project = project.id INNER JOIN software_for_project ON project.id = software_for_project.project WHERE @@ -871,7 +875,8 @@ CREATE OR REPLACE FUNCTION unique_team_members() RETURNS TABLE ( orcid VARCHAR, given_names VARCHAR, family_names VARCHAR, - email_address VARCHAR + email_address VARCHAR, + avatar_id VARCHAR ) LANGUAGE plpgsql STABLE AS $$ BEGIN @@ -882,7 +887,8 @@ BEGIN c.orcid, c.given_names, c.family_names, - c.email_address + c.email_address, + c.avatar_id FROM team_member c ORDER BY @@ -986,7 +992,7 @@ CREATE FUNCTION projects_by_maintainer(maintainer_id UUID) RETURNS TABLE ( updated_at TIMESTAMPTZ, is_published BOOLEAN, image_contain BOOLEAN, - image_id UUID + image_id VARCHAR ) LANGUAGE plpgsql STABLE AS $$ BEGIN @@ -1005,11 +1011,9 @@ BEGIN project.updated_at, project.is_published, project.image_contain, - image_for_project.project AS image_id + project.image_id FROM project - LEFT JOIN - image_for_project ON project.id = image_for_project.project INNER JOIN maintainer_for_project ON project.id = maintainer_for_project.project WHERE @@ -1029,7 +1033,7 @@ CREATE FUNCTION organisations_by_maintainer(maintainer_id UUID) RETURNS TABLE ( ror_id VARCHAR, website VARCHAR, is_tenant BOOLEAN, - logo_id UUID, + logo_id VARCHAR, software_cnt BIGINT, project_cnt BIGINT, children_cnt BIGINT, @@ -1047,15 +1051,13 @@ BEGIN organisation.ror_id, organisation.website, organisation.is_tenant, - logo_for_organisation.organisation AS logo_id, + organisation.logo_id, software_count_by_organisation.software_cnt, project_count_by_organisation.project_cnt, children_count_by_organisation.children_cnt, organisation_route.rsd_path FROM organisation - LEFT JOIN - logo_for_organisation ON logo_for_organisation.organisation = organisation.id LEFT JOIN software_count_by_organisation() ON software_count_by_organisation.organisation = organisation.id LEFT JOIN @@ -1256,7 +1258,7 @@ CREATE FUNCTION project_search() RETURNS TABLE ( updated_at TIMESTAMPTZ, is_published BOOLEAN, image_contain BOOLEAN, - image_id UUID, + image_id VARCHAR, keywords citext[], keywords_text TEXT, research_domain VARCHAR[], @@ -1279,15 +1281,13 @@ BEGIN project.updated_at, project.is_published, project.image_contain, - image_for_project.project AS image_id, + project.image_id, keyword_filter_for_project.keywords, keyword_filter_for_project.keywords_text, research_domain_filter_for_project.research_domain, research_domain_filter_for_project.research_domain_text FROM project - LEFT JOIN - image_for_project ON project.id = image_for_project.project LEFT JOIN keyword_filter_for_project() ON project.id=keyword_filter_for_project.project LEFT JOIN @@ -1296,7 +1296,6 @@ BEGIN END $$; - -- RESEARCH DOMAIN count used in project filter -- to show used research domains with count CREATE FUNCTION research_domain_count_for_projects() RETURNS TABLE ( @@ -1384,4 +1383,44 @@ BEGIN RETURN QUERY organisation ; END -$$; \ No newline at end of file +$$; + +-- ALL unique persons in RSD (contributors and team members) +-- TO BE USED IN SEARCH +-- NOTE! UNION takes care of duplicate entries +CREATE FUNCTION unique_persons() RETURNS TABLE ( + display_name TEXT, + affiliation VARCHAR, + orcid VARCHAR, + given_names VARCHAR, + family_names VARCHAR, + email_address VARCHAR, + avatar_id VARCHAR +) LANGUAGE plpgsql STABLE AS +$$ +BEGIN RETURN QUERY + SELECT + unique_contributors.display_name, + unique_contributors.affiliation, + unique_contributors.orcid, + unique_contributors.given_names, + unique_contributors.family_names, + unique_contributors.email_address, + unique_contributors.avatar_id + FROM + unique_contributors() + UNION + SELECT + unique_team_members.display_name, + unique_team_members.affiliation, + unique_team_members.orcid, + unique_team_members.given_names, + unique_team_members.family_names, + unique_team_members.email_address, + unique_team_members.avatar_id + FROM + unique_team_members() + ORDER BY + display_name ASC; +END +$$; diff --git a/deployment/docker-compose.yml b/deployment/docker-compose.yml index eca833173..a27079563 100644 --- a/deployment/docker-compose.yml +++ b/deployment/docker-compose.yml @@ -4,6 +4,7 @@ # SPDX-FileCopyrightText: 2022 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences # SPDX-FileCopyrightText: 2022 Netherlands eScience Center # SPDX-FileCopyrightText: 2022 dv4all +# SPDX-FileCopyrightText: 2022 Helmholtz Centre for Environmental Research (UFZ) # # SPDX-License-Identifier: Apache-2.0 @@ -38,7 +39,7 @@ services: - 3500 environment: # it needs to be here to use values from .env file - - PGRST_DB_URI=postgres://authenticator:${POSTGRES_AUTHENTICATOR_PASSWORD}@database:5432/${POSTGRES_DB} + - PGRST_DB_URI=postgres://authenticator:${POSTGRES_AUTHENTICATOR_PASSWORD}@${POSTGRES_DB_HOST}:${POSTGRES_DB_HOST_PORT}/${POSTGRES_DB} - PGRST_DB_ANON_ROLE - PGRST_DB_SCHEMA - PGRST_SERVER_PORT diff --git a/docker-compose.yml b/docker-compose.yml index 16373a36a..1a8307c51 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,7 @@ # SPDX-FileCopyrightText: 2022 Christian Meeßen (GFZ) # SPDX-FileCopyrightText: 2022 Helmholtz Centre Potsdam - GFZ German Research Centre for Geosciences # SPDX-FileCopyrightText: 2022 Matthias Rüster (GFZ) +# SPDX-FileCopyrightText: 2022 Helmholtz Centre for Environmental Research (UFZ) # # SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: EUPL-1.2 @@ -14,7 +15,7 @@ version: "3.0" services: database: build: ./database - image: rsd/database:1.6.4 + image: rsd/database:2.0.0 ports: # enable connection from outside (development mode) - "5432:5432" @@ -34,12 +35,12 @@ services: backend: build: ./backend-postgrest - image: rsd/backend-postgrest:1.1.0 + image: rsd/backend-postgrest:1.11.2 expose: - 3500 environment: # it needs to be here to use values from .env file - - PGRST_DB_URI=postgres://authenticator:${POSTGRES_AUTHENTICATOR_PASSWORD}@database:5432/${POSTGRES_DB} + - PGRST_DB_URI=postgres://authenticator:${POSTGRES_AUTHENTICATOR_PASSWORD}@${POSTGRES_DB_HOST}:${POSTGRES_DB_HOST_PORT}/${POSTGRES_DB} - PGRST_DB_ANON_ROLE - PGRST_DB_SCHEMA - PGRST_SERVER_PORT @@ -92,7 +93,7 @@ services: # dockerfile to use for build dockerfile: Dockerfile # update version number to correspond to frontend/package.json - image: rsd/frontend:1.9.1 + image: rsd/frontend:1.11.2 environment: # it uses values from .env file - POSTGREST_URL @@ -202,7 +203,7 @@ services: - DUID - DGID # update version number to correspond to frontend/package.json - image: rsd/frontend-dev:1.9.1 + image: rsd/frontend-dev:1.11.2 ports: - "3000:3000" - "9229:9229" diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index 8204ffa4b..a84d7d453 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -1,6 +1,7 @@ { "extends": "next/core-web-vitals", "rules": { + "no-debugger":"warn", "no-console": "warn", "eol-last": [ "warn", diff --git a/frontend/README.md b/frontend/README.md index 3f9aae240..8553c971d 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -163,11 +163,13 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next Upgrading minor version changes can be usally done using `yarn outdated` and `yarn upgrade`. Major updates are more demanding and might require changes in the source code. +Since RSD went live in August 2022 we started using exact versions in the package.json to avoid unexpected upgrades. This means that we manually check for outdated packages and perform "controlled" upgrades. At the same time we perfom security audits using `yarn audit`. + ### Next and React ```bash -# upgrade next and react -yarn add next react react-dom typescript +# upgrade next, react and typescript +yarn add next@latest react@latest react-dom@latest eslint-config-next@latest typescript # upgrade types yarn add -D @types/node @types/react @types/react-dom ``` diff --git a/frontend/__tests__/__fixtures__/apiContributors.json b/frontend/__tests__/__fixtures__/apiContributors.json index fd64e7fb4..4055cf344 100644 --- a/frontend/__tests__/__fixtures__/apiContributors.json +++ b/frontend/__tests__/__fixtures__/apiContributors.json @@ -9,6 +9,7 @@ "affiliation": null, "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -21,6 +22,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -33,6 +35,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -45,6 +48,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -57,6 +61,7 @@ "affiliation": "CWI", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -69,6 +74,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -81,6 +87,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -93,6 +100,7 @@ "affiliation": "CWI", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -105,6 +113,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -117,6 +126,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -129,6 +139,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null }, { @@ -141,6 +152,7 @@ "affiliation": "Netherlands eScience Center", "role": null, "orcid": null, + "avatar_id": null, "position": null } ] \ No newline at end of file diff --git a/frontend/auth/index.test.tsx b/frontend/auth/index.test.tsx index 4526d687d..7e0a865f3 100644 --- a/frontend/auth/index.test.tsx +++ b/frontend/auth/index.test.tsx @@ -5,7 +5,6 @@ import {render, screen, waitFor} from '@testing-library/react' import {AuthProvider, useAuth, REFRESH_MARGIN, getSessionSeverSide, Session} from './index' -import * as refreshSession from './refreshSession' const session:Session = { user: null, @@ -13,11 +12,11 @@ const session:Session = { status: 'loading' } -// mock refreshSession call -const mockRefreshSession = jest.spyOn(refreshSession, 'refreshSession') -mockRefreshSession.mockImplementation(() => { - // console.log('Calling mockRefreshSession') - return Promise.resolve(session) +const mockRefreshSession = jest.fn(()=>Promise.resolve(session)) +jest.mock('./refreshSession', () => { + return { + refreshSession: jest.fn(()=> mockRefreshSession()) + } }) function ChildComponent() { diff --git a/frontend/components/AppFooter/MarkdownPages.tsx b/frontend/components/AppFooter/MarkdownPages.tsx index 9298a3038..c2fe51a09 100644 --- a/frontend/components/AppFooter/MarkdownPages.tsx +++ b/frontend/components/AppFooter/MarkdownPages.tsx @@ -18,8 +18,10 @@ export default function MarkdownPages({pages=[]}: { pages: RsdLink[] }) { return ( - {page.title} + href={`/page/${page.slug}`} + className="hover:text-primary" + passHref> + {page.title} ) })} diff --git a/frontend/components/AppHeader/AppHeader.test.tsx b/frontend/components/AppHeader/AppHeader.test.tsx index 6c1ed3fef..fdd420a0f 100644 --- a/frontend/components/AppHeader/AppHeader.test.tsx +++ b/frontend/components/AppHeader/AppHeader.test.tsx @@ -30,7 +30,7 @@ it('renders AppHeader with header tag', () => { it('renders AppHeader with 2 searchboxes', () => { // has searchbox - const search = screen.getAllByRole('searchbox') + const search = screen.getAllByTestId('global-search') // two searchboxes, one for mobile and one for larger screens?!? expect(search).toHaveLength(2) }) @@ -38,12 +38,12 @@ it('renders AppHeader with 2 searchboxes', () => { it('renders AppHeader with links and logo link', () => { // has searchbox const links = screen.getAllByRole('link') - // menu items + logo link to root - expect(links).toHaveLength(menuItems.length + 1) + // menu items + logo link + feedback link + expect(links).toHaveLength(menuItems.length + 2) // screen.debug() }) -it.only('renders AppHeader with Sign in link', async() => { +it('renders AppHeader with Sign in link', async() => { // has searchbox const link = await screen.findByText('Sign in') // link should exists diff --git a/frontend/components/AppHeader/index.tsx b/frontend/components/AppHeader/index.tsx index c43d0ad41..af34cc047 100644 --- a/frontend/components/AppHeader/index.tsx +++ b/frontend/components/AppHeader/index.tsx @@ -60,11 +60,9 @@ export default function AppHeader() {
- - - - - + + + @@ -73,10 +71,8 @@ export default function AppHeader() {
{menuItems.map(item => - - - {item.label} - + + {item.label} )}
@@ -133,10 +129,8 @@ export default function AppHeader() { > {menuItems.map(item => - - - {item.label} - + + {item.label} )} diff --git a/frontend/components/GlobalSearchAutocomplete/index.tsx b/frontend/components/GlobalSearchAutocomplete/index.tsx index c663114d8..ea837aae5 100644 --- a/frontend/components/GlobalSearchAutocomplete/index.tsx +++ b/frontend/components/GlobalSearchAutocomplete/index.tsx @@ -138,6 +138,7 @@ export default function GlobalSearchAutocomplete(props: Props) {
We use  - - - cookies - + + cookies + with  - - - matomo.org - - to provide a better user experience. + + matomo.org + to provide a better user experience.
- - - Read more - + + Read more
diff --git a/frontend/components/home/rsd/index.tsx b/frontend/components/home/rsd/index.tsx index 150e36871..62e73f284 100644 --- a/frontend/components/home/rsd/index.tsx +++ b/frontend/components/home/rsd/index.tsx @@ -7,7 +7,7 @@ import {useEffect} from 'react' import AOS from 'aos' import Link from 'next/link' -import Image from 'next/image' +import Image from 'next/legacy/image' import useRsdSettings from '~/config/useRsdSettings' import {config} from './config' @@ -39,23 +39,26 @@ export type RsdHomeProps = { } function GlowingButton({text,url,target='_self',minWidth='9rem'}: {text: string, url: string, target?:string, minWidth?:string}) { - return - -
-
-
- - {text} - -
+ return +
+ } @@ -108,10 +111,7 @@ export default function RsdHome({software_cnt, project_cnt, organisation_cnt, co
- {/* Divider */} - {/* */} - - {/* Stats */} + {/* stats */}
{software_cnt} Software
diff --git a/frontend/components/layout/TagChipFilter.tsx b/frontend/components/layout/TagChipFilter.tsx index da92d42d2..741fa65c0 100644 --- a/frontend/components/layout/TagChipFilter.tsx +++ b/frontend/components/layout/TagChipFilter.tsx @@ -17,7 +17,6 @@ export default function TagChipFilter({url, label, title}: href={url} passHref > - - ) } diff --git a/frontend/components/login/LoginButton.tsx b/frontend/components/login/LoginButton.tsx index 2b00f7dce..f175d2098 100644 --- a/frontend/components/login/LoginButton.tsx +++ b/frontend/components/login/LoginButton.tsx @@ -64,11 +64,10 @@ export default function LoginButton() { return ( - - Sign in - + Sign in ) } diff --git a/frontend/components/login/LoginDialog.tsx b/frontend/components/login/LoginDialog.tsx index 60b0659a9..49edd2905 100644 --- a/frontend/components/login/LoginDialog.tsx +++ b/frontend/components/login/LoginDialog.tsx @@ -61,7 +61,6 @@ export default function LoginDialog({providers,open, onClose}: LoginDialogProps) href={provider.redirectUrl} passHref > - - ) })} diff --git a/frontend/components/mention/FindMention.test.tsx b/frontend/components/mention/FindMention.test.tsx index 437ec69f4..2153eba8f 100644 --- a/frontend/components/mention/FindMention.test.tsx +++ b/frontend/components/mention/FindMention.test.tsx @@ -25,7 +25,8 @@ const mockMentionItem = { image_url: null, // is_featured?: boolean mention_type: 'book' as MentionTypeKeys, - source: 'crossref' + source: 'crossref', + note: null } let props:FindMentionProps = { @@ -77,7 +78,7 @@ it('has working cancel button when freeSolo', async () => { expect(loader).not.toBeInTheDocument() }) -it('shows custom notFound message when freeSolo AND onCreate NOT provided', async () => { +it('shows custom notFound message when freeSolo=true AND onCreate=undefined', async () => { const notFound = 'Tested not found message' props.config = { ...props.config, @@ -99,14 +100,16 @@ it('shows custom notFound message when freeSolo AND onCreate NOT provided', asyn // input test value const searchInput = screen.getByRole('combobox') const searchFor = 'test' - fireEvent.change(searchInput, {target: {value: searchFor}}) - // need to advance all timers for debounce etc... // Note! it needs to be wrapped in act - await act(() => { + act(() => { + fireEvent.change(searchInput, {target: {value: searchFor}}) jest.runOnlyPendingTimers() }) + // then wait for loader to be removed + await waitForElementToBeRemoved(() => screen.getByTestId('circular-loader')) + // wait for listbox and notFound message await waitFor(() => { const options = screen.getByRole('listbox') @@ -128,14 +131,17 @@ it('does not show Add option when onCreate=undefined', async () => { // input test value const searchInput = screen.getByRole('combobox') const searchFor = 'test' - fireEvent.change(searchInput, {target: {value: searchFor}}) // need to advance all timers for debounce etc... // Note! it needs to be wrapped in act - await act(() => { + act(() => { + fireEvent.change(searchInput, {target: {value: searchFor}}) jest.runOnlyPendingTimers() }) + // then wait for loader to be removed + await waitForElementToBeRemoved(() => screen.getByTestId('circular-loader')) + // select only option in dropdown const options = screen.getAllByRole('option') expect(options.length).toEqual(2) @@ -158,19 +164,22 @@ it('shows Add option when onCreate defined', async () => { // input test value const searchInput = screen.getByRole('combobox') const searchFor = 'test' - fireEvent.change(searchInput, {target: {value: searchFor}}) // need to advance all timers for debounce etc... // Note! it needs to be wrapped in act - await act(() => { + act(() => { + fireEvent.change(searchInput, {target: {value: searchFor}}) jest.runOnlyPendingTimers() }) + // then wait for loader to be removed + await waitForElementToBeRemoved(() => screen.getByTestId('circular-loader')) + // select only options in dropdown const options = screen.getAllByRole('option') expect(options.length).toEqual(3) - // find Add est + // find Add test const add = screen.getByText(`Add "${searchFor}"`) expect(add).toBeInTheDocument() @@ -193,14 +202,18 @@ it('leaves input after selection when reset=false', async () => { // input test value const searchInput = screen.getByRole('combobox') const searchFor = 'test' - fireEvent.change(searchInput, {target: {value: searchFor}}) // need to advance all timers for debounce etc... // Note! it needs to be wrapped in act - await act(() => { + act(() => { + fireEvent.change(searchInput, {target: {value: searchFor}}) jest.runOnlyPendingTimers() }) + // then wait for loader to be removed + // requied for rest of the test to pass + await waitForElementToBeRemoved(() => screen.getByTestId('circular-loader')) + // select only option in dropdown const options = screen.getAllByRole('option') expect(options.length).toEqual(2) @@ -224,14 +237,18 @@ it('removes input after selection when reset=true', async () => { // input test value const searchInput = screen.getByRole('combobox') const searchFor = 'test' - fireEvent.change(searchInput, {target: {value: searchFor}}) // need to advance all timers for debounce etc... // Note! it needs to be wrapped in act - await act(() => { + act(() => { + fireEvent.change(searchInput, {target: {value: searchFor}}) jest.runOnlyPendingTimers() }) + // then wait for loader to be removed + // requied for rest of the test to pass + await waitForElementToBeRemoved(() => screen.getByTestId('circular-loader')) + const options = screen.getAllByRole('option') expect(options.length).toEqual(2) // select option diff --git a/frontend/components/mention/MentionItemFeatured.tsx b/frontend/components/mention/MentionItemFeatured.tsx index b09c65807..836335441 100644 --- a/frontend/components/mention/MentionItemFeatured.tsx +++ b/frontend/components/mention/MentionItemFeatured.tsx @@ -14,31 +14,31 @@ export default function MentionItemFeatured({mention}: { mention: MentionItemPro if (!mention || mention.url===null) return null return ( - - -
- -
-

- {mention.title} -

- {/*
By {mention.authors}
*/} - - -
-
-
+ +
+ +
+

+ {mention.title} +

+ {/*
By {mention.authors}
*/} + + +
+
) } diff --git a/frontend/components/mention/MentionViewItem.tsx b/frontend/components/mention/MentionViewItem.tsx index 91c4c22f6..7160f2daa 100644 --- a/frontend/components/mention/MentionViewItem.tsx +++ b/frontend/components/mention/MentionViewItem.tsx @@ -51,10 +51,8 @@ export default function MentionViewItem({item, pos}: {item: MentionItemProps, po if (item?.url) { return ( - - - {renderItemBody()} - + + {renderItemBody()} ) } diff --git a/frontend/components/mention/useSearchFn.tsx b/frontend/components/mention/useSearchFn.tsx index f2cd2d2f8..fd2065f65 100644 --- a/frontend/components/mention/useSearchFn.tsx +++ b/frontend/components/mention/useSearchFn.tsx @@ -61,7 +61,7 @@ export default function useSearchFn({searchFor, searchFn}: useSearchFnProps) { searchForItems() } return () => { - debugger + // debugger abort=true } }, [searchFor, searchFn]) diff --git a/frontend/components/organisation/Breadcrumbs.tsx b/frontend/components/organisation/Breadcrumbs.tsx index befdc2f87..300ee3206 100644 --- a/frontend/components/organisation/Breadcrumbs.tsx +++ b/frontend/components/organisation/Breadcrumbs.tsx @@ -27,8 +27,9 @@ export default function Breadcrumbs({segments}: - {item.label} + {item.label} ) } else { diff --git a/frontend/components/organisation/OrganisationCard.tsx b/frontend/components/organisation/OrganisationCard.tsx index 24b75bfe3..3c7f5aa4c 100644 --- a/frontend/components/organisation/OrganisationCard.tsx +++ b/frontend/components/organisation/OrganisationCard.tsx @@ -5,7 +5,7 @@ import Link from 'next/link' import {OrganisationForOverview} from '../../types/Organisation' -import {getUrlFromLogoId} from '../../utils/editOrganisation' +import {getImageUrl} from '~/utils/editImage' import StatCounter from '../layout/StatCounter' import VerifiedIcon from '@mui/icons-material/Verified' import SingleLineTitle from '../layout/SingleLineTitle' @@ -28,68 +28,65 @@ export default function OrganisationCard(organisation: OrganisationForOverview) return ( - -
- {/*

{organisation.name}

*/} -
- + {/*

{organisation.name}

*/} +
+ + {organisation.name} + + { + organisation.is_tenant && + + } +
+
+
+ - {organisation.name} - - { - organisation.is_tenant && - - } + />
-
-
- -
-
- - -
+
+ +
-
-
+
+ ) } diff --git a/frontend/components/organisation/metadata/Links.tsx b/frontend/components/organisation/metadata/Links.tsx index 0ccd7d712..3da03c545 100644 --- a/frontend/components/organisation/metadata/Links.tsx +++ b/frontend/components/organisation/metadata/Links.tsx @@ -35,10 +35,9 @@ export default function Links({links=[]}:{links:LinksProps[]}) { key={item.url} href={item.url} passHref + target="_blank" > - - {item.icon} {item.title} - + {item.icon} {item.title} ) diff --git a/frontend/components/organisation/metadata/OrganisationLogo.tsx b/frontend/components/organisation/metadata/OrganisationLogo.tsx index 157392728..961209150 100644 --- a/frontend/components/organisation/metadata/OrganisationLogo.tsx +++ b/frontend/components/organisation/metadata/OrganisationLogo.tsx @@ -3,17 +3,18 @@ // // SPDX-License-Identifier: Apache-2.0 -import {useEffect, useState} from 'react' +import {ChangeEvent, useEffect, useState} from 'react' import DeleteIcon from '@mui/icons-material/Delete' import EditIcon from '@mui/icons-material/Edit' import {useSession} from '~/auth' import useSnackbar from '../../snackbar/useSnackbar' -import {deleteOrganisationLogo, getUrlFromLogoId, uploadOrganisationLogo} from '../../../utils/editOrganisation' -import logger from '../../../utils/logger' +import {patchOrganisation} from '../../../utils/editOrganisation' import LogoAvatar from '~/components/layout/LogoAvatar' import IconButton from '@mui/material/IconButton' +import {deleteImage, getImageUrl, upsertImage} from '~/utils/editImage' +import {handleFileUpload} from '~/utils/handleFileUpload' type OrganisationLogoProps = { id: string @@ -23,116 +24,101 @@ type OrganisationLogoProps = { isMaintainer: boolean } -type LogoProps = { - id: string | null - b64: string | null - mime_type: string | null -} - export default function OrganisationLogo({id,name,logo_id,isMaintainer}: OrganisationLogoProps) { const {token} = useSession() const {showWarningMessage,showErrorMessage} = useSnackbar() // currently shown image - // after new upload uses b64 prop - const [logo, setLogo] = useState({ - id: logo_id, - b64: null, - mime_type: null - }) - // new to upload image - const [upload, setUpload] = useState({ - id: null, - b64: null, - mime_type:null - }) - - useEffect(() => { - if (id) { - setLogo({ - id: logo_id, - b64: null, - mime_type: null - }) - } - },[id,logo_id]) + const [logo, setLogo] = useState(null) + // console.group('OrganisationLogo') + // console.log('id...', id) + // console.log('name...', name) + // console.log('logo_id...', logo_id) + // console.log('isMaintainer...', isMaintainer) + // console.groupEnd() + // Update logo when new value + // received from parent useEffect(() => { - let abort = false - async function uploadLogo({id, b64, mime_type, token}: - {id: string, b64: string, mime_type: string, token: string }) { - const resp = await uploadOrganisationLogo({ - id, - // send just b64 data - data:b64.split(',')[1], - mime_type, - token - }) - if (abort) return - // update local state - setLogo({ - id, - b64, - mime_type - }) - // fetch image to reload the cache - await fetch(`/image/rpc/get_logo?id=${id}`, {cache: 'reload'}) - // @ts-ignore (hard) reload the page, true is for FF - location.reload(true) + if (logo_id) setLogo(logo_id) + },[logo_id]) + + async function onFileUpload(e:ChangeEvent|undefined) { + if (typeof e !== 'undefined') { + const {status, message, image_b64, image_mime_type} = await handleFileUpload(e) + if (status === 200 && image_b64 && image_mime_type) { + addLogo({ + data: image_b64, + mime_type: image_mime_type + }) + } else if (status===413) { + showWarningMessage(message) + } else { + showErrorMessage(message) + } } - if (upload.id && upload.b64 && upload.mime_type && token) { - uploadLogo({ - id: upload.id, - b64: upload.b64, - mime_type: upload.mime_type, + } + + async function addLogo({data, mime_type}: { data: string, mime_type: string }) { + // split base64 to use only encoded content + const b64data = data.split(',')[1] + const resp = await upsertImage({ + data:b64data, + mime_type, + token + }) + if (resp.status === 201) { + // update logo_id reference + const patch = await patchOrganisation({ + data: { + id, + logo_id: resp.message + }, token }) - } - return ()=>{abort=true} - },[upload,token]) - - function handleFileUpload({target}:{target: any}) { - try { - let file = target.files[0] - if (typeof file == 'undefined') return - // check file size - if (file.size > 2097152) { - // file is to large > 2MB - showWarningMessage('The file is too large. Please select image < 2MB.') - return - } - let reader = new FileReader() - reader.onloadend = function () { - if (reader.result) { - // write to new avatar b64 - setUpload({ - id, - b64: reader.result as string, - mime_type: file.type + if (patch.status === 200) { + // if we are replacing existing logo + if (logo !== null && resp.message && + logo !== resp.message + ) { + // try to remove old logo from db + // do not await for result + // NOTE! delete MUST be after pathing organisation + // because we are removing logo_id reference + deleteImage({ + id: logo, + token }) } + setLogo(resp.message) + } else { + showErrorMessage(`Failed to upload logo. ${resp.message}`) } - reader.readAsDataURL(file) - } catch (e:any) { - logger(`handleFileUpload: ${e.message}`,'error') + } else { + showErrorMessage(`Failed to upload logo. ${resp.message}`) } } async function removeLogo() { - if (logo.id && token) { - const resp = await deleteOrganisationLogo({ - id: logo.id, + if (logo && token) { + // remove logo_id from organisation + const resp = await patchOrganisation({ + data: { + id, + logo_id: null + }, token }) - if (resp.status !== 200) { - showErrorMessage(`Failed to remove logo. ${resp.message}`) - } else { - setLogo({ - id: null, - b64: null, - mime_type:null + if (resp.status == 200) { + // delete logo without check + const del = await deleteImage({ + id: logo, + token }) + setLogo(null) + } else { + showErrorMessage(`Failed to remove logo. ${resp.message}`) } } } @@ -141,7 +127,7 @@ export default function OrganisationLogo({id,name,logo_id,isMaintainer}: return ( ) } @@ -163,7 +149,7 @@ export default function OrganisationLogo({id,name,logo_id,isMaintainer}: id="upload-avatar-image" type="file" accept="image/*" - onChange={handleFileUpload} + onChange={onFileUpload} style={{display:'none'}} /> diff --git a/frontend/components/organisation/metadata/RorLocation.tsx b/frontend/components/organisation/metadata/RorLocation.tsx index 86a7b990a..3edd74d5e 100644 --- a/frontend/components/organisation/metadata/RorLocation.tsx +++ b/frontend/components/organisation/metadata/RorLocation.tsx @@ -23,8 +23,8 @@ export default function RorLocation({meta}: { meta: RORItem | null }) { -
{location.city}, {country}
- ) diff --git a/frontend/components/organisation/metadata/index.tsx b/frontend/components/organisation/metadata/index.tsx index 64f78b8af..75744aadb 100644 --- a/frontend/components/organisation/metadata/index.tsx +++ b/frontend/components/organisation/metadata/index.tsx @@ -64,8 +64,11 @@ export default function OrganisationMetadata({organisation, meta, isMaintainer}: }} > diff --git a/frontend/components/organisation/settings/updateOrganisationSettings.tsx b/frontend/components/organisation/settings/updateOrganisationSettings.tsx index c4199c2c8..542571a72 100644 --- a/frontend/components/organisation/settings/updateOrganisationSettings.tsx +++ b/frontend/components/organisation/settings/updateOrganisationSettings.tsx @@ -3,8 +3,7 @@ // // SPDX-License-Identifier: Apache-2.0 -import {OrganisationForOverview} from '~/types/Organisation' -import {columsForUpdate} from '~/utils/editOrganisation' +import {columsForUpdate, OrganisationForOverview} from '~/types/Organisation' import {createJsonHeaders, extractReturnMessage} from '~/utils/fetchHelpers' import {getPropsFromObject} from '~/utils/getPropsFromObject' diff --git a/frontend/components/organisation/units/ResearchUnitItem.tsx b/frontend/components/organisation/units/ResearchUnitItem.tsx index d440f4fd1..3e2e4e55f 100644 --- a/frontend/components/organisation/units/ResearchUnitItem.tsx +++ b/frontend/components/organisation/units/ResearchUnitItem.tsx @@ -11,7 +11,7 @@ import Avatar from '@mui/material/Avatar' import IconButton from '@mui/material/IconButton' import EditIcon from '@mui/icons-material/Edit' -import {getUrlFromLogoId} from '../../../utils/editOrganisation' +import {getImageUrl} from '~/utils/editImage' import {useRouter} from 'next/router' type UnitListItemProps = { @@ -91,7 +91,7 @@ export default function UnitItem({pos,slug,name,website,logo_id,isMaintainer,onE passHref> - - {name} - + {name} } secondary={getSecondaryLabel()} diff --git a/frontend/components/organisation/units/ResearchUnitModal.tsx b/frontend/components/organisation/units/ResearchUnitModal.tsx index d3c3dc729..cf44cd627 100644 --- a/frontend/components/organisation/units/ResearchUnitModal.tsx +++ b/frontend/components/organisation/units/ResearchUnitModal.tsx @@ -14,21 +14,22 @@ import { import DeleteIcon from '@mui/icons-material/Delete' import {useForm} from 'react-hook-form' +import {useSession} from '~/auth' import useSnackbar from '../../snackbar/useSnackbar' import ControlledTextField from '../../form/ControlledTextField' import {EditOrganisation} from '../../../types/Organisation' import {organisationInformation as config} from '../organisationConfig' -import {getUrlFromLogoId} from '../../../utils/editOrganisation' +import {deleteImage, getImageUrl} from '~/utils/editImage' import logger from '../../../utils/logger' - import {getSlugFromString} from '../../../utils/getSlugFromString' import SubmitButtonWithListener from '~/components/form/SubmitButtonWithListener' + type EditOrganisationModalProps = { open: boolean, onCancel: () => void, onSubmit: ({data, pos}: { data: EditOrganisation, pos?: number }) => void, - onDeleteLogo: (logo_id:string) => void, + // onDeleteLogo: (logo_id:string) => void, organisation?: EditOrganisation, // item position in the array pos?: number @@ -37,9 +38,10 @@ type EditOrganisationModalProps = { const formId='research-unit-modal' -export default function EditOrganisationModal({ - open, onCancel, onSubmit, onDeleteLogo, organisation, pos, title = 'Organisation' +export default function ResearchUnitModal({ + open, onCancel, onSubmit, organisation, pos, title = 'Organisation' }: EditOrganisationModalProps) { + const {token} = useSession() const {showWarningMessage} = useSnackbar() const smallScreen = useMediaQuery('(max-width:600px)') const [baseUrl, setBaseUrl] = useState('') @@ -99,8 +101,12 @@ export default function EditOrganisationModal({ reader.onloadend = function () { if (reader.result) { // write to new avatar b64 - setValue('logo_b64', reader.result as string) - setValue('logo_mime_type', file.type,{shouldDirty: true}) + // setValue('logo_b64', reader.result as string) + // setValue('logo_mime_type', file.type, { shouldDirty: true }) + replaceLogo( + reader.result as string, + file.type + ) } } reader.readAsDataURL(file) @@ -109,11 +115,32 @@ export default function EditOrganisationModal({ } } - function deleteLogoFromDb() { + async function replaceLogo(logo_b64:string, logo_mime_type:string) { if (formData.logo_id) { - onDeleteLogo(formData.logo_id) + // remove old logo from db + const del = await deleteImage({ + id: formData.logo_id, + token + }) + setValue('logo_id', null) + } + // write new logo to logo_b64 + // we upload the image after submit + setValue('logo_b64', logo_b64) + setValue('logo_mime_type', logo_mime_type, {shouldDirty: true}) + } + + async function deleteLogo() { + if (formData.logo_id) { + // remove old logo from db + const del = await deleteImage({ + id: formData.logo_id, + token + }) } setValue('logo_id', null) + setValue('logo_b64', null) + setValue('logo_mime_type', null, {shouldDirty: true}) } return ( @@ -147,6 +174,9 @@ export default function EditOrganisationModal({ + { - if (formData?.logo_b64) { - setValue('logo_b64', null) - } - if (formData.logo_id) { - deleteLogoFromDb() - } - setValue('logo_mime_type',null,{shouldDirty: true}) - }} + onClick={deleteLogo} > remove diff --git a/frontend/components/organisation/units/index.tsx b/frontend/components/organisation/units/index.tsx index f4e6b1254..50609e00d 100644 --- a/frontend/components/organisation/units/index.tsx +++ b/frontend/components/organisation/units/index.tsx @@ -11,17 +11,22 @@ import Button from '@mui/material/Button' import {useSession} from '~/auth' import useSnackbar from '../../snackbar/useSnackbar' import ContentLoader from '../../layout/ContentLoader' -import {EditOrganisation, OrganisationForOverview} from '../../../types/Organisation' import { - createOrganisation, deleteOrganisationLogo, - newOrganisationProps, updateOrganisation, - updateDataObjectAfterSave + columsForCreate, columsForUpdate, CoreOrganisationProps, + EditOrganisation, Organisation, OrganisationForOverview +} from '../../../types/Organisation' +import { + createOrganisation, + newOrganisationProps, + updateOrganisation } from '../../../utils/editOrganisation' import useOrganisationUnits from '../../../utils/useOrganisationUnits' import {sortOnStrProp} from '../../../utils/sortFn' import ResearchUnitList from './ResearchUnitList' import ResearchUnitModal from './ResearchUnitModal' import {OrganisationComponentsProps} from '../OrganisationNavItems' +import {upsertImage} from '~/utils/editImage' +import {getPropsFromObject} from '~/utils/getPropsFromObject' type EditOrganisationModal = { open: boolean, @@ -117,40 +122,53 @@ export default function ResearchUnits({organisation}: OrganisationComponentsProp async function saveOrganisation({data, pos}:{data: EditOrganisation, pos?: number }) { try { + // UPLOAD logo + if (data.logo_b64 && data.logo_mime_type) { + // split base64 to use only encoded content + const b64data = data.logo_b64.split(',')[1] + const upload = await upsertImage({ + data: b64data, + mime_type: data.logo_mime_type, + token + }) + // debugger + if (upload.status === 201) { + // update data values + data.logo_id = upload.message + // remove image strings after upload + data.logo_b64 = null + data.logo_mime_type = null + } else { + showErrorMessage(`Failed to upload image. ${upload.message}`) + return + } + } + // SAVE organisation if (typeof pos != 'undefined' && data.id) { + const unit:Organisation = getPropsFromObject(data,columsForUpdate) // update existing organisation const resp = await updateOrganisation({ - item: data, + organisation: unit, token }) + // debugger if (resp.status !== 200) { showErrorMessage(resp.message) } else { - if (data.logo_b64) { - const updatedUnit = updateDataObjectAfterSave({ - data, - id: data.id - }) - updateUnitInList(updatedUnit, pos) - // @ts-ignore (hard) reload the page, true is for FF - location.reload(true) - } else { - updateUnitInList(data,pos) - } + updateUnitInList(data,pos) closeModals() } } else { // create new organisation + const unit:CoreOrganisationProps = getPropsFromObject(data, columsForCreate) const resp = await createOrganisation({ - item: data, + organisation:unit, token }) + // debugger if (resp.status === 201) { - const newUnit = updateDataObjectAfterSave({ - data, - id: resp.message - }) - addUnitToCollection(newUnit) + data.id = resp.message + addUnitToCollection(data) closeModals() } else { showErrorMessage(resp.message) @@ -161,16 +179,6 @@ export default function ResearchUnits({organisation}: OrganisationComponentsProp } } - async function onDeleteOrganisationLogo(logo_id: string) { - const resp = await deleteOrganisationLogo({ - id: logo_id, - token - }) - if (resp.status !== 200) { - showErrorMessage(resp.message) - } - } - function onEditUnit(pos: number) { // TODO! missing primary maintainer! // console.log('ResearchUnits: TODO! on edit unit...', pos) @@ -222,7 +230,6 @@ export default function ResearchUnits({organisation}: OrganisationComponentsProp organisation={modal.organisation} onCancel={closeModals} onSubmit={saveOrganisation} - onDeleteLogo={onDeleteOrganisationLogo} /> ) diff --git a/frontend/components/projects/ProjectCard.tsx b/frontend/components/projects/ProjectCard.tsx index a36fd22ec..de9c0a69e 100644 --- a/frontend/components/projects/ProjectCard.tsx +++ b/frontend/components/projects/ProjectCard.tsx @@ -7,7 +7,7 @@ import Link from 'next/link' import {getTimeAgoSince} from '../../utils/dateFn' import ImageAsBackground from '../layout/ImageAsBackground' -import {getImageUrl} from '../../utils/getProjects' +import {getImageUrl} from '../../utils/editImage' import FeaturedIcon from '~/components/icons/FeaturedIcon' import NotPublishedIcon from '~/components/icons/NotPublishedIcon' @@ -55,43 +55,44 @@ export default function ProjectCard( } return ( - - -
+ + ) } diff --git a/frontend/components/projects/ProjectDescription.tsx b/frontend/components/projects/ProjectDescription.tsx index 146dd419f..a1de26ff6 100644 --- a/frontend/components/projects/ProjectDescription.tsx +++ b/frontend/components/projects/ProjectDescription.tsx @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: Apache-2.0 -import {getImageUrl} from '../../utils/getProjects' +import {getImageUrl} from '../../utils/editImage' import ImageAsBackground from '../layout/ImageAsBackground' import ReactMarkdownWithSettings from '../layout/ReactMarkdownWithSettings' @@ -41,7 +41,7 @@ export default function ProjectDescription( return null } return ( -
+
{getImage()} - -
  • - {item.name} -
  • -
    +
  • + {item.name} +
  • ) })} diff --git a/frontend/components/projects/ProjectLinks.tsx b/frontend/components/projects/ProjectLinks.tsx index 8cc8b87d0..25590b79c 100644 --- a/frontend/components/projects/ProjectLinks.tsx +++ b/frontend/components/projects/ProjectLinks.tsx @@ -27,13 +27,12 @@ export default function ProjectLinks({links}: { links: ProjectLink[] }) { - -
  • - {link.title} -
  • -
    +
  • + {link.title} +
  • ) } diff --git a/frontend/components/projects/add/AddProjectCard.test.tsx b/frontend/components/projects/add/AddProjectCard.test.tsx index b227f04c5..cccb9cda7 100644 --- a/frontend/components/projects/add/AddProjectCard.test.tsx +++ b/frontend/components/projects/add/AddProjectCard.test.tsx @@ -11,20 +11,22 @@ import AddProjectCard from './AddProjectCard' import {addConfig} from './addProjectConfig' import {getSlugFromString} from '../../../utils/getSlugFromString' -// mock addSoftware -import * as editProject from '../../../utils/editProject' - -// mock addProject -const mockAddProject = jest.spyOn(editProject, 'addProject') - .mockImplementation((props) => Promise.resolve({status: 201, message: props})) -// mock validSoftwareItem -const mockValidProjectItem = jest.spyOn(editProject, 'validProjectItem') - .mockImplementation((props) => new Promise((res, rej) => { - // console.log('validProjectItem') +const mockAddProject = jest.fn((props)=>Promise.resolve({status: 201, message: props})) +const mockValidProjectItem = jest.fn((slug,token) => { + // console.log('validProjectItem...props...',slug,token) + return new Promise((res, rej) => { setTimeout(() => { res(false) - },10) - })) + }, 10) + }) +}) + +jest.mock('~/utils/editProject', () => { + return { + addProject: jest.fn((props)=> mockAddProject(props)), + validProjectItem: jest.fn((slug,token)=> mockValidProjectItem(slug,token)) + } +}) // mock next router const mockBack = jest.fn() @@ -36,39 +38,50 @@ jest.mock('next/router', () => ({ }) })) -it('render card with title', async () => { - render(WrappedComponentWithProps(AddProjectCard)) - const title = await screen.queryByText(addConfig.title) - await act(() => { - expect(title).toBeInTheDocument() - }) +// prepare +jest.useFakeTimers() + +afterEach(() => { + jest.runOnlyPendingTimers() + jest.clearAllMocks() }) -it('card has textbox with Title that can be entered', async() => { +it('render card with title, subtitle and slug', () => { render(WrappedComponentWithProps(AddProjectCard)) - // dummy input value - const inputSubtitle = 'Test project title' - const title = screen.getByRole('textbox', {name: 'Title'}) - expect(title).toBeInTheDocument() + const title = screen.getByRole('textbox', {name: addConfig.project_title.label}) + const subtitle = screen.getByRole('textbox', {name: addConfig.project_subtitle.label}) + const slug = screen.getByRole('textbox',{name: addConfig.project_subtitle.label}) - // accepts test value - fireEvent.change(title, {target: {value: inputSubtitle}}) - await act(() => { - expect(title.value).toEqual(inputSubtitle) - }) + expect(title).toBeInTheDocument() + expect(subtitle).toBeInTheDocument() + expect(slug).toBeInTheDocument() }) -it('card has textbox with Subtitle that can be entered', async() => { +it('card has textbox with Title that can be entered', async() => { + render(WrappedComponentWithProps(AddProjectCard)) - const desc = screen.getByRole('textbox', {name: 'Subtitle'}) - expect(desc).toBeInTheDocument() - // accepts test value - const inputSubtitle = 'Test project description' - fireEvent.change(desc, {target: {value: inputSubtitle}}) - await act(() => { - expect(desc.value).toEqual(inputSubtitle) + // check title + const title:HTMLInputElement = screen.getByRole('textbox', {name: addConfig.project_title.label}) + expect(title).toBeInTheDocument() + + // dummy input value + const inputTitle = 'Test project title' + act(() => { + // accepts test value + fireEvent.change(title, {target: {value: inputTitle}}) + jest.runAllTimers() }) + + // confirm slug validation in progress + // REQUIRED! to avoid act warning/error shown + const loader = await screen.findByTestId('slug-circular-progress') + expect(loader).toBeInTheDocument() + // confirm that loader is removed + await waitForElementToBeRemoved(loader) + + // validate value + expect(title.value).toEqual(inputTitle) }) it('card has cancel and submit buttons', async() => { @@ -106,6 +119,7 @@ it('validate, save and redirect', async () => { status: 'authenticated' } const slug = getSlugFromString(inputTitle) + // render render(WrappedComponentWithProps(AddProjectCard,{ session @@ -128,6 +142,7 @@ it('validate, save and redirect', async () => { // save const save = screen.getByRole('button', {name: 'Save'}) + // validate expect(save).toBeInTheDocument() expect(title.value).toEqual(inputTitle) expect(desc.value).toEqual(inputSubtitle) @@ -152,7 +167,8 @@ it('validate, save and redirect', async () => { date_end: null, image_caption: null, image_contain: false, - grant_id: null + grant_id: null, + image_id: null }, 'token': 'TEST_TOKEN', }) diff --git a/frontend/components/projects/add/AddProjectCard.tsx b/frontend/components/projects/add/AddProjectCard.tsx index 6746768a4..19de24384 100644 --- a/frontend/components/projects/add/AddProjectCard.tsx +++ b/frontend/components/projects/add/AddProjectCard.tsx @@ -44,7 +44,6 @@ export default function AddProjectCard() { const router = useRouter() const [baseUrl, setBaseUrl] = useState('') const [slugValue, setSlugValue] = useState('') - const [validSlug, setValidSlug] = useState('') const [validating, setValidating]=useState(false) const [state, setState] = useState(initalState) const {register, handleSubmit, watch, formState, setError, setValue} = useForm({ @@ -68,15 +67,17 @@ export default function AddProjectCard() { }, []) /** - * Convert brand_name value into slugValue. + * Convert project_title value into slugValue. * The slugValue is then debounced and produces bouncedSlug * We use bouncedSlug value later on to perform call to api */ useEffect(() => { // construct slug from title - const slugValue = getSlugFromString(project_title) - // update slugValue - setSlugValue(slugValue) + if (project_title) { + const slugValue = getSlugFromString(project_title) + // update slugValue + setSlugValue(slugValue) + } }, [project_title]) /** * When bouncedSlug value is changed, @@ -84,9 +85,11 @@ export default function AddProjectCard() { * This change occures when brand_name value is changed */ useEffect(() => { - setValue('slug', bouncedSlug, { - shouldValidate: true - }) + if (bouncedSlug) { + setValue('slug', bouncedSlug, { + shouldValidate: true + }) + } }, [bouncedSlug, setValue]) /** * When slug value is changed by debounce or manually by user @@ -139,7 +142,8 @@ export default function AddProjectCard() { date_end: null, image_caption: null, image_contain: false, - grant_id: null + grant_id: null, + image_id: null } // add software to database addProject({ diff --git a/frontend/components/projects/edit/information/AutosaveFundingOrganisations.tsx b/frontend/components/projects/edit/information/AutosaveFundingOrganisations.tsx index 90a946db0..878373a57 100644 --- a/frontend/components/projects/edit/information/AutosaveFundingOrganisations.tsx +++ b/frontend/components/projects/edit/information/AutosaveFundingOrganisations.tsx @@ -8,44 +8,21 @@ import {useState} from 'react' import {useSession} from '~/auth' import useSnackbar from '~/components/snackbar/useSnackbar' -import {EditOrganisation, FundingOrganisation, SearchOrganisation} from '~/types/Organisation' +import {columsForCreate, SearchOrganisation} from '~/types/Organisation' import {createOrganisation, searchForOrganisation} from '~/utils/editOrganisation' import {addOrganisationToProject, deleteOrganisationFromProject} from '~/utils/editProject' +import {getPropsFromObject} from '~/utils/getPropsFromObject' import {getSlugFromString} from '~/utils/getSlugFromString' import FindOrganisation from '../FindOrganisation' import {projectInformation as config} from './config' -function createNewOrganisation(organisation:SearchOrganisation){ - const newOrganisation: EditOrganisation = { - id: organisation.id, - parent: organisation.parent, - slug: organisation.slug ? organisation.slug : getSlugFromString(organisation.name), - // funding organisation without primary maintainer - primary_maintainer: organisation.primary_maintainer, - name: organisation.name, - ror_id: organisation.ror_id, - is_tenant: organisation.is_tenant, - website: organisation.website, - // indicates image already present - logo_id: organisation.logo_id, - // new image to upload - logo_b64: null, - logo_mime_type: null, - position: null, - // funding organisation come from ROR - source: organisation.source, - description: null - } - return newOrganisation -} - type FundingOrganisationProps={ id:string, - items: FundingOrganisation[] + items: SearchOrganisation[] } export default function FundingOrganisations({id,items}:FundingOrganisationProps) { - const session = useSession() + const {token} = useSession() const {showErrorMessage,showInfoMessage} = useSnackbar() const [organisations,setOrganisations] = useState(items) @@ -54,41 +31,45 @@ export default function FundingOrganisations({id,items}:FundingOrganisationProps const find = organisations.filter(item => item.name === selected.name) if (find.length === 0) { let resp - let organisation + // create slug if not present + if (selected.slug===null) { + selected.slug = getSlugFromString(selected.name) + } if (selected.id===null){ - organisation = createNewOrganisation(selected) + const organisation = getPropsFromObject(selected,columsForCreate) + // createNewOrganisation(selected) resp = await createOrganisation({ - item: organisation, - token: session.token + organisation, + token }) // debugger if (resp.status == 201) { // we receive organisation id - organisation.id = resp.message + selected.id = resp.message as string // and we add organisation to project // as funding organisation resp = await addOrganisationToProject({ project: id, - organisation: resp.message, + organisation: selected.id, role: 'funding', position: null, - session + token }) } } else { - organisation = createNewOrganisation(selected) + // organisation = getPropsFromObject(selected,columsForUpdate) resp = await addOrganisationToProject({ project: id, - organisation: organisation.id as string, + organisation: selected.id as string, role: 'funding', position: null, - session + token }) } if (resp.status===200){ const items = [ ...organisations, - organisation + selected ] setOrganisations(items) }else{ @@ -106,7 +87,7 @@ export default function FundingOrganisations({id,items}:FundingOrganisationProps project: id, organisation: item.id, role: 'funding', - token: session.token + token }) if (resp.status === 200){ const items=[ diff --git a/frontend/components/projects/edit/information/AutosaveProjectImage.tsx b/frontend/components/projects/edit/information/AutosaveProjectImage.tsx index 899061045..8ff1ad4f5 100644 --- a/frontend/components/projects/edit/information/AutosaveProjectImage.tsx +++ b/frontend/components/projects/edit/information/AutosaveProjectImage.tsx @@ -14,13 +14,14 @@ import {useSession} from '~/auth' import ImageAsBackground from '~/components/layout/ImageAsBackground' import useSnackbar from '~/components/snackbar/useSnackbar' import {EditProject} from '~/types/Project' -import {getImageUrl} from '~/utils/getProjects' -import logger from '~/utils/logger' -import {addImage, deleteImage, updateImage} from '~/utils/editProject' +import {getImageUrl} from '~/utils/editImage' import AutosaveProjectTextField from './AutosaveProjectTextField' import AutosaveProjectSwitch from './AutosaveProjectSwitch' import {projectInformation as config} from './config' import {patchProjectTable} from './patchProjectInfo' +import {upsertImage,deleteImage} from '~/utils/editImage' +import {ChangeEvent} from 'react' +import {handleFileUpload} from '~/utils/handleFileUpload' export default function AutosaveProjectImage() { const {token} = useSession() @@ -37,57 +38,63 @@ export default function AutosaveProjectImage() { let resp // split base64 to use only encoded content const data = image_b64.split(',')[1] - if (form_image_id && form_image_id !== null) { - // update image - resp = await updateImage({ - project: form_id, - data, - mime_type, - token - }) - await fetch(`/image/rpc/get_project_image?id=${form_id}`, {cache: 'reload'}) - // @ts-ignore (hard) reload the page, true is for FF - location.reload(true) - } else { - // add new image - resp = await addImage({ - project: form_id, - data, - mime_type, + if (form_image_id) { + const patch = await patchProjectTable({ + id: form_id, + data: { + image_id: null + }, token }) + if (patch.status === 200) { + // try to remove old image + // but don't wait for results + const del = await deleteImage({ + id: form_image_id, + token + }) + } } - if (resp.status === 200) { + // add new image to db + resp = await upsertImage({ + data, + mime_type, + token + }) + if (resp.status !== 201) { + showErrorMessage(`Failed to save image. ${resp.message}`) + return + } + const patch = await patchProjectTable({ + id:form_id, + data: { + image_id:resp.message + }, + token + }) + if (patch.status === 200) { // setValue works while resetField doesn't, not sure why? - setValue('image_b64', image_b64 as string) - setValue('image_mime_type', mime_type) + // setValue('image_b64', image_b64 as string) + // setValue('image_mime_type', mime_type) // remove id for now - setValue('image_id', null) + setValue('image_id', resp.message) + // debugger } else { showErrorMessage(`Failed to save image. ${resp.message}`) } } - function handleFileUpload({target}:{target: any}) { - try { - let file = target.files[0] - if (typeof file == 'undefined') return - // check file size - if (file.size > 2097152) { - // file is to large > 2MB - showWarningMessage('The file is too large. Please select image < 2MB.') - return + async function onFileUpload(e:ChangeEvent|undefined) { + if (typeof e !== 'undefined') { + const {status, message, image_b64, image_mime_type} = await handleFileUpload(e) + if (status === 200 && image_b64 && image_mime_type) { + // save image + saveImage(image_b64,image_mime_type) + } else if (status===413) { + showWarningMessage(message) + } else { + showErrorMessage(message) } - let reader = new FileReader() - reader.onloadend = function () { - if (reader.result) { - // save image - saveImage(reader.result as string,file.type) - } - } - reader.readAsDataURL(file) - } catch (e:any) { - logger(`ProjectImage.handleFileUpload: ${e.message}`,'error') } } @@ -103,35 +110,34 @@ export default function AutosaveProjectImage() { async function removeImage() { // remove image - let resp = await deleteImage({ - project: form_id, - token - }) - if (resp.status === 200) { - // clear all image values in the form - if (form_image_b64) setValue('image_b64', null) - if (form_image_mime_type) setValue('image_mime_type', null) - if (form_image_id) setValue('image_id', null) - } else { - showErrorMessage(`Failed to remove image. ${resp.message}`) - return - } - // reset image attributes - // we do not show error message on failure - resp = await patchProjectTable({ + const resp = await patchProjectTable({ id: form_id, data: { + image_id: null, image_caption: null, image_contain: false }, token }) - if (resp.status === 200) { + // clear all image values in the form + if (form_image_b64) setValue('image_b64', null) + if (form_image_mime_type) setValue('image_mime_type', null) + if (form_image_id) { + // try to remove old image + // but don't wait for results + const del = await deleteImage({ + id: form_image_id, + token + }) + setValue('image_id', null) + } + // reset form values resetField('image_caption', {defaultValue: null}) - resetField('image_contain',{defaultValue:false}) + resetField('image_contain', {defaultValue: false}) } else { - logger(`AutosaveProjectImage.patchImageCaption failed. ${resp.message}`,'warn') + showErrorMessage(`Failed to remove image. ${resp.message}`) + return } } @@ -210,7 +216,7 @@ export default function AutosaveProjectImage() { id="upload-avatar-image" type="file" accept="image/*" - onChange={handleFileUpload} + onChange={onFileUpload} style={{display:'none'}} /> diff --git a/frontend/components/projects/edit/information/PublishingProjectInfo.tsx b/frontend/components/projects/edit/information/PublishingProjectInfo.tsx index 7eda779db..dc5e29bea 100644 --- a/frontend/components/projects/edit/information/PublishingProjectInfo.tsx +++ b/frontend/components/projects/edit/information/PublishingProjectInfo.tsx @@ -18,7 +18,7 @@ export default function PublishingProjectInfo() { Publishing project page Setting the page status to published will expose the project page to all visitors. Unpublished project can be found under - your profile + your profile page. ) diff --git a/frontend/components/projects/edit/information/index.tsx b/frontend/components/projects/edit/information/index.tsx index fddc3e565..d1fffc9e9 100644 --- a/frontend/components/projects/edit/information/index.tsx +++ b/frontend/components/projects/edit/information/index.tsx @@ -82,7 +82,7 @@ export default function EditProjectInformation({slug}: {slug: string}) { /> {/* middle panel */} -
    +
    diff --git a/frontend/components/projects/edit/information/useProjectToEdit.tsx b/frontend/components/projects/edit/information/useProjectToEdit.tsx index 547d9b8d3..0978ce6d4 100644 --- a/frontend/components/projects/edit/information/useProjectToEdit.tsx +++ b/frontend/components/projects/edit/information/useProjectToEdit.tsx @@ -4,7 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 import {useEffect,useState} from 'react' -import {FundingOrganisation} from '~/types/Organisation' +import {SearchOrganisation} from '~/types/Organisation' import {EditProject, OrganisationsOfProject, ProjectLink} from '~/types/Project' import {getKeywordsForProject, getLinksForProject, getOrganisationsOfProject, getProjectItem, getResearchDomainsForProject} from '~/utils/getProjects' @@ -25,7 +25,7 @@ function prepareUrlForProject(url_for_project:ProjectLink[]) { } function prepareFundingOrganisations(organisations:OrganisationsOfProject[]) { - const data:FundingOrganisation[] = organisations.map((item, pos) => { + const data:SearchOrganisation[] = organisations.map((item, pos) => { return { ...item, pos, diff --git a/frontend/components/projects/edit/organisations/index.tsx b/frontend/components/projects/edit/organisations/index.tsx index 5f0da1ef5..6acaaee2d 100644 --- a/frontend/components/projects/edit/organisations/index.tsx +++ b/frontend/components/projects/edit/organisations/index.tsx @@ -19,11 +19,11 @@ import EditOrganisationModal from '~/components/software/edit/organisations/Edit import ConfirmDeleteModal from '~/components/layout/ConfirmDeleteModal' import {EditOrganisationModalProps} from '~/components/software/edit/organisations' import {ModalStates} from '~/components/software/edit/editSoftwareTypes' -import {EditOrganisation, SearchOrganisation} from '~/types/Organisation' +import {columsForUpdate, EditOrganisation, SearchOrganisation} from '~/types/Organisation' import useSnackbar from '~/components/snackbar/useSnackbar' import { - deleteOrganisationLogo, newOrganisationProps, - saveExistingOrganisation, searchToEditOrganisation + newOrganisationProps, + searchToEditOrganisation, updateOrganisation } from '~/utils/editOrganisation' import {getSlugFromString} from '~/utils/getSlugFromString' import { @@ -31,15 +31,17 @@ import { deleteOrganisationFromProject, patchOrganisationPositions } from '~/utils/editProject' import SortableOrganisationsList from '~/components/software/edit/organisations/SortableOrganisationsList' +import {upsertImage} from '~/utils/editImage' +import {getPropsFromObject} from '~/utils/getPropsFromObject' export default function ProjectOrganisations({slug}: { slug: string }) { - const session = useSession() + const {token,user} = useSession() const {showErrorMessage,showInfoMessage} = useSnackbar() const {project} = useProjectContext() const {loading, organisations, setOrganisations} = useParticipatingOrganisations({ project: project.id, - token: session.token, - account: session.user?.account + token: token, + account: user?.account }) const [modal, setModal] = useState>({ edit: { @@ -50,11 +52,15 @@ export default function ProjectOrganisations({slug}: { slug: string }) { } }) + // console.group('ProjectOrganisations') + // console.log('organisations...', organisations) + // console.groupEnd() + async function onAddOrganisation(item: SearchOrganisation) { // add default values const addOrganisation: EditOrganisation = searchToEditOrganisation({ item, - account: session.user?.account, + account: user?.account, position: organisations.length + 1 }) // check if present by ror_id @@ -81,7 +87,7 @@ export default function ProjectOrganisations({slug}: { slug: string }) { organisation: addOrganisation.id ?? '', role: 'participating', position: addOrganisation.position, - session + token }) if (resp.status === 200) { // update status received in message @@ -158,7 +164,7 @@ export default function ProjectOrganisations({slug}: { slug: string }) { project: project.id, organisation: organisation.id, role: organisation.role ?? 'participating', - token: session.token + token }) if (resp.status === 200) { deleteOrganisationFromList(pos) @@ -170,30 +176,56 @@ export default function ProjectOrganisations({slug}: { slug: string }) { async function saveOrganisation({data, pos}:{data: EditOrganisation, pos?: number }) { try { - closeModals() + // UPLOAD logo + if (data.logo_b64 && data.logo_mime_type) { + // split base64 to use only encoded content + const b64data = data.logo_b64.split(',')[1] + const upload = await upsertImage({ + data: b64data, + mime_type: data.logo_mime_type, + token + }) + // debugger + if (upload.status === 201) { + // update data values + data.logo_id = upload.message + // remove image strings after upload + data.logo_b64 = null + data.logo_mime_type = null + } else { + showErrorMessage(`Failed to upload image. ${upload.message}`) + return + } + } + // SAVE organisation if (typeof pos != 'undefined' && data.id) { + // extract data for update + const organisation = getPropsFromObject(data,columsForUpdate) // update existing organisation - const resp = await saveExistingOrganisation({ - item: data, - token: session?.token, - pos, - setState: updateOrganisationInList + const resp = await updateOrganisation({ + organisation, + token }) - if (resp.status !== 200) { + if (resp.status === 200) { + updateOrganisationInList(data,pos) + closeModals() + } else { showErrorMessage(resp.message) } } else { // create slug for new organisation based on name data.slug = getSlugFromString(data.name) // create new organisation and add it - const resp = await createOrganisationAndAddToProject({ + const {status,message} = await createOrganisationAndAddToProject({ project: project.id, item: data, - session, - setState: addOrganisationToList + token }) - if (resp.status !== 200) { - showErrorMessage(resp.message) + if (status === 200) { + addOrganisationToList(message) + closeModals() + } else { + showErrorMessage(message) } } } catch (e:any) { @@ -201,16 +233,6 @@ export default function ProjectOrganisations({slug}: { slug: string }) { } } - async function onDeleteOrganisationLogo(logo_id:string) { - const resp = await deleteOrganisationLogo({ - id: logo_id, - token: session.token - }) - if (resp.status !== 200) { - showErrorMessage(resp.message) - } - } - function closeModals() { setModal({ edit: { @@ -257,7 +279,7 @@ export default function ProjectOrganisations({slug}: { slug: string }) { const resp = await patchOrganisationPositions({ project: project.id, organisations, - token: session.token + token }) if (resp.status === 200) { setOrganisations(organisations) @@ -307,7 +329,6 @@ export default function ProjectOrganisations({slug}: { slug: string }) { organisation={modal.edit.organisation} onCancel={closeModals} onSubmit={saveOrganisation} - onDeleteLogo={onDeleteOrganisationLogo} /> []>([]) + const [options, setOptions] = useState[]>([]) const [status, setStatus] = useState<{ loading: boolean, foundFor: string | undefined @@ -52,7 +53,7 @@ export default function FindMember({onAdd,project,token}:FindMemberProps) { }) } - function addMember(selected:AutocompleteOption) { + function addMember(selected:AutocompleteOption) { if (selected && selected.data) { onAdd({ ...selected.data, @@ -60,7 +61,9 @@ export default function FindMember({onAdd,project,token}:FindMemberProps) { project, is_contact_person: false, role: null, - position: null + position: null, + // RSD entries could have avatar + avatar_id: selected.data.avatar_id ?? null }) } } @@ -77,7 +80,7 @@ export default function FindMember({onAdd,project,token}:FindMemberProps) { affiliation: null, role: null, orcid: null, - avatar_data: null, + avatar_id: null, avatar_mime_type: null, avatar_b64: null, position: null @@ -85,7 +88,7 @@ export default function FindMember({onAdd,project,token}:FindMemberProps) { } function renderAddOption(props: HTMLAttributes, - option: AutocompleteOption) { + option: AutocompleteOption) { // if more than one option we add border at the bottom // we assume that first option is Add "new item" if (options.length > 1) { @@ -104,7 +107,7 @@ export default function FindMember({onAdd,project,token}:FindMemberProps) { } function renderOption(props: HTMLAttributes, - option: AutocompleteOption) { + option: AutocompleteOption) { // console.log('renderOption...', option) // when value is not found option returns input prop if (option?.input) { diff --git a/frontend/components/projects/edit/team/SortableTeamMemberItem.tsx b/frontend/components/projects/edit/team/SortableTeamMemberItem.tsx index 3eb53ae65..751d41d16 100644 --- a/frontend/components/projects/edit/team/SortableTeamMemberItem.tsx +++ b/frontend/components/projects/edit/team/SortableTeamMemberItem.tsx @@ -14,6 +14,7 @@ import {combineRoleAndAffiliation, getDisplayInitials, getDisplayName} from '~/u import SortableListItemActions from '~/components/layout/SortableListItemActions' import {TeamMember} from '~/types/Project' import {useMediaQuery} from '@mui/material' +import {getImageUrl} from '~/utils/editImage' type TeamMemberProps = { pos: number, @@ -67,7 +68,7 @@ export default function SortableTeamMemberItem({pos, item, onEdit, onDelete}: Te {smallScreen ? null : diff --git a/frontend/components/projects/edit/team/TeamMemberModal.tsx b/frontend/components/projects/edit/team/TeamMemberModal.tsx index 8c1104919..4fbe61aa8 100644 --- a/frontend/components/projects/edit/team/TeamMemberModal.tsx +++ b/frontend/components/projects/edit/team/TeamMemberModal.tsx @@ -5,7 +5,7 @@ // // SPDX-License-Identifier: Apache-2.0 -import {useEffect,useState} from 'react' +import {ChangeEvent, useEffect} from 'react' import { Button, Dialog, DialogActions, DialogContent, DialogTitle, useMediaQuery @@ -13,7 +13,7 @@ import { import DeleteIcon from '@mui/icons-material/Delete' import {useForm} from 'react-hook-form' -import logger from '~/utils/logger' +import {useSession} from '~/auth' import {getDisplayInitials, getDisplayName} from '~/utils/getDisplayName' import {TeamMember} from '~/types/Project' import useSnackbar from '~/components/snackbar/useSnackbar' @@ -23,6 +23,9 @@ import ContributorAvatar from '~/components/software/ContributorAvatar' import ControlledAffiliation from '~/components/form/ControlledAffiliation' import {cfgTeamMembers as config} from './config' import SubmitButtonWithListener from '~/components/form/SubmitButtonWithListener' +import {handleFileUpload} from '~/utils/handleFileUpload' +import {deleteImage, getImageUrl} from '~/utils/editImage' +import {patchTeamMember} from './editTeamMembers' type TeamMemberModalProps = { open: boolean, @@ -35,14 +38,13 @@ type TeamMemberModalProps = { const formId='edit-team-member-modal' export default function TeamMemberModal({open, onCancel, onSubmit, member, pos}: TeamMemberModalProps) { - const {showWarningMessage} = useSnackbar() + const {token} = useSession() + const {showWarningMessage,showErrorMessage} = useSnackbar() const smallScreen = useMediaQuery('(max-width:600px)') - const [b64Image, setB64Image]=useState() const {handleSubmit, watch, formState, reset, control, register, setValue} = useForm({ mode: 'onChange', defaultValues: { - ...member, - avatar_b64:null + ...member } }) @@ -50,6 +52,11 @@ export default function TeamMemberModal({open, onCancel, onSubmit, member, pos}: const {isValid, isDirty} = formState const formData = watch() + // console.group('TeamMemberModal') + // console.log('isDirty...', isDirty) + // console.log('isValid...', isValid) + // console.groupEnd() + useEffect(() => { if (member) { reset(member) @@ -59,44 +66,82 @@ export default function TeamMemberModal({open, onCancel, onSubmit, member, pos}: function handleCancel() { // reset form reset() - // remove image upload - setB64Image(undefined) // hide onCancel() } - function handleFileUpload({target}:{target: any}) { - try { - let file = target.files[0] - if (typeof file == 'undefined') return - // check file size - if (file.size > 2097152) { - // file is to large > 2MB - showWarningMessage('The file is too large. Please select image < 2MB.') - return - } - let reader = new FileReader() - reader.onloadend = function () { - if (reader.result) { - // write to new avatar b64 - setValue('avatar_b64', reader.result as string) - setValue('avatar_mime_type', file.type,{shouldDirty: true}) - } + async function onFileUpload(e:ChangeEvent|undefined) { + if (typeof e !== 'undefined') { + const {status, message, image_b64, image_mime_type} = await handleFileUpload(e) + if (status === 200 && image_b64 && image_mime_type) { + replaceImage(image_b64, image_mime_type) + } else if (status===413) { + showWarningMessage(message) + } else { + showErrorMessage(message) } - reader.readAsDataURL(file) - } catch (e:any) { - logger(`handleFileUpload: ${e.message}`,'error') } } - function getAvatarUrl() { - if (formData?.avatar_b64 && formData?.avatar_b64?.length > 10) { - return formData?.avatar_b64 + async function replaceImage(avatar_b64:string, avatar_mime_type:string) { + if (formData.id && formData.avatar_id) { + // remove refrence to avatar first + const patch = await patchTeamMember({ + member: { + id: formData.id, + avatar_id: null + }, + token + }) + // debugger + if (patch.status !== 200) { + showErrorMessage('Failed to remove image') + return + } + // then try to remove avatar from db + // without waiting for result + const del = await deleteImage({ + id: formData.avatar_id, + token + }) + // remove id in the form too + setValue('avatar_id', null) } - if (formData?.avatar_url && formData?.avatar_url.length > 10) { - return formData?.avatar_url + // write new logo to logo_b64 + // we upload the image after submit + setValue('avatar_b64', avatar_b64) + setValue('avatar_mime_type', avatar_mime_type, {shouldDirty: true}) + } + + async function deleteAvatar() { + if (formData.id && formData.avatar_id) { + // remove refrence to avatar first + const patch = await patchTeamMember({ + member: { + id: formData.id, + avatar_id: null + }, + token + }) + // debugger + if (patch.status !== 200) { + showErrorMessage('Failed to remove image') + return + } + // then try to remove avatar from db + // without waiting for result + const del = await deleteImage({ + id: formData.avatar_id, + token + }) + // update form + setValue('avatar_id', null, {shouldDirty: true,shouldValidate:true}) + } else { + // just remove uploaded image from form + // because it is not save yet to DB + setValue('avatar_b64', null) + setValue('avatar_mime_type', null, {shouldDirty: true}) } - return '' } return ( @@ -128,10 +173,10 @@ export default function TeamMemberModal({open, onCancel, onSubmit, member, pos}: {...register('project')} /> @@ -153,23 +198,15 @@ export default function TeamMemberModal({open, onCancel, onSubmit, member, pos}: id="upload-avatar-image" type="file" accept="image/*" - onChange={handleFileUpload} + onChange={onFileUpload} style={{display:'none'}} />
    diff --git a/frontend/components/projects/edit/team/editTeamMembers.ts b/frontend/components/projects/edit/team/editTeamMembers.ts index deca6dde2..4b7fa2208 100644 --- a/frontend/components/projects/edit/team/editTeamMembers.ts +++ b/frontend/components/projects/edit/team/editTeamMembers.ts @@ -3,11 +3,9 @@ // // SPDX-License-Identifier: Apache-2.0 -import {TeamMemberProps} from '~/types/Contributor' -import {TeamMember} from '~/types/Project' +import {PatchPerson} from '~/types/Contributor' +import {SaveTeamMember, TeamMember} from '~/types/Project' import {createJsonHeaders, extractReturnMessage} from '~/utils/fetchHelpers' -import {getAvatarUrl} from '~/utils/getProjects' -import {getPropsFromObject} from '~/utils/getPropsFromObject' import logger from '~/utils/logger' export type ModalProps = { @@ -24,73 +22,8 @@ export type ModalStates = { delete: DeleteModalProps } - -export async function createTeamMember({data, token}: - { data: TeamMember, token: string }) { - - const resp = await postTeamMember({ - member: prepareMemberData(data), - token - }) - - if (resp.status === 201) { - data.id = resp.message - const member = removeBase64Data(data) - return { - status: 201, - message: member - } - } - - return resp -} - -export async function updateTeamMember({data, token}: - { data: TeamMember, token: string }) { - - const member = prepareMemberData(data) - const resp = await patchTeamMember({member, token}) - - if (resp.status === 200) { - // if we uploaded new image we remove - // data and construct avatar_url - const returned = removeBase64Data(data) - // reload image to update cache - if (returned.avatar_url) await fetch(returned.avatar_url, {cache: 'reload'}) - return { - status: 200, - message: returned - } - } else { - return resp - } -} - -export function prepareMemberData(data: TeamMember) { - const member = getPropsFromObject(data, TeamMemberProps) - // do we need to save new base64 image - if (data?.avatar_b64 && - data?.avatar_b64.length > 10 && - data?.avatar_mime_type !== null) { - // split base64 to use only encoded content - member.avatar_data = data?.avatar_b64.split(',')[1] - } - return member -} - -export function removeBase64Data(member: TeamMember) { - if (member.avatar_b64 && - member?.avatar_b64.length > 10) { - // clean it from memory data - member.avatar_b64 = null - // and we use avatar url instead - member.avatar_url = getAvatarUrl(member) - } - return member -} - export async function postTeamMember({member, token}: - { member: TeamMember, token: string }) { + { member: SaveTeamMember, token: string }) { try { const url = '/api/v1/team_member' @@ -124,7 +57,7 @@ export async function postTeamMember({member, token}: } export async function patchTeamMember({member, token}: - {member: TeamMember, token: string }) { + { member: PatchPerson, token: string }) { try { const url = `/api/v1/team_member?id=eq.${member.id}` const resp = await fetch(url, { @@ -144,7 +77,6 @@ export async function patchTeamMember({member, token}: } } - export async function deleteTeamMemberById({ids, token}: { ids: string[], token: string }) { try { const url = `/api/v1/team_member?id=in.("${ids.join('","')}")` diff --git a/frontend/components/projects/edit/team/index.tsx b/frontend/components/projects/edit/team/index.tsx index 933dd4051..61fc13ef9 100644 --- a/frontend/components/projects/edit/team/index.tsx +++ b/frontend/components/projects/edit/team/index.tsx @@ -13,16 +13,19 @@ import ConfirmDeleteModal from '~/components/layout/ConfirmDeleteModal' import ContentLoader from '~/components/layout/ContentLoader' import EditSection from '~/components/layout/EditSection' import EditSectionTitle from '~/components/layout/EditSectionTitle' -import {TeamMember} from '~/types/Project' +import {SaveTeamMember, TeamMember} from '~/types/Project' import {cfgTeamMembers} from './config' import FindMember from './FindMember' import { - createTeamMember, deleteTeamMemberById, - ModalProps, ModalStates, patchTeamMemberPositions, updateTeamMember + deleteTeamMemberById, ModalProps, ModalStates, + patchTeamMember, patchTeamMemberPositions, postTeamMember } from './editTeamMembers' import TeamMemberModal from './TeamMemberModal' import useTeamMembers from './useTeamMembers' import SortableTeamMemberList from './SortableTeamMemberList' +import {deleteImage, upsertImage} from '~/utils/editImage' +import {getPropsFromObject} from '~/utils/getPropsFromObject' +import {TeamMemberProps} from '~/types/Contributor' type EditMemberModal = ModalProps & { member?: TeamMember @@ -130,41 +133,74 @@ export default function ProjectTeam({slug}: { slug: string }) { }) // renumber remaining members await sortTeamMembers(newMembersList) + // try to remove member avatar + // without waiting for result + if (member.avatar_id) { + const del = await deleteImage({ + id: member.avatar_id, + token + }) + } } else { showErrorMessage(`Failed to remove member. ${resp.message}`) } } } - async function onSubmitMember({data,pos}:{data: TeamMember, pos?: number}) { - hideModals() + async function onSubmitMember({data, pos}: { data: TeamMember, pos?: number }) { + // UPLOAD avatar + if (data.avatar_b64 && data.avatar_mime_type) { + // split base64 to use only encoded content + const b64data = data.avatar_b64.split(',')[1] + const upload = await upsertImage({ + data: b64data, + mime_type: data.avatar_mime_type, + token + }) + // debugger + if (upload.status === 201) { + // update data values + data.avatar_id = upload.message + } else { + showErrorMessage(`Failed to upload image. ${upload.message}`) + return + } + } + // ensure project id if (!data.project) { // add project id data.project = project.id } - if (data?.id && typeof pos != 'undefined') { - const resp = await updateTeamMember({ - data, + // prepare member object for save (remove helper props) + const member:SaveTeamMember = getPropsFromObject(data, TeamMemberProps) + // CREATE or UPDATE + if (member.id && typeof pos !== 'undefined') { + const resp = await patchTeamMember({ + member, token }) + // debugger if (resp.status === 200) { - // updated record delivered in message - const member = resp.message - updateLocalState(member,pos) + // on success update local state + updateLocalState(member, pos) + hideModals() } else { showErrorMessage(`Failed to update member. ${resp.message}`) } } else { // define items postion at the end - data.position = members.length + 1 - const resp = await createTeamMember({ - data, + member.position = members.length + 1 + const resp = await postTeamMember({ + member, token }) + // debugger if (resp.status === 201) { - // updated record delivered in message - const member = resp.message + // get id out of message + member.id = resp.message + // update local state updateLocalState(member) + hideModals() } else { showErrorMessage(`Failed to add member. ${resp.message}`) } diff --git a/frontend/components/projects/edit/team/searchForMember.ts b/frontend/components/projects/edit/team/searchForMember.ts index be39607ef..e675d7c93 100644 --- a/frontend/components/projects/edit/team/searchForMember.ts +++ b/frontend/components/projects/edit/team/searchForMember.ts @@ -5,10 +5,8 @@ // // SPDX-License-Identifier: Apache-2.0 -import {AutocompleteOption} from '~/types/AutocompleteOptions' -import {SearchTeamMember} from '~/types/Project' -import {createJsonHeaders} from '~/utils/fetchHelpers' -import {getORCID, isOrcid} from '~/utils/getORCID' +import {findRSDPerson} from '~/utils/findRSDPerson' +import {getORCID} from '~/utils/getORCID' import logger from '../../../../utils/logger' export type Keyword = { @@ -26,7 +24,7 @@ export async function searchForMember({searchFor,token,frontend=true}: {searchFor: string,token:string,frontend?:boolean}) { try { const [rsdContributor, orcidOptions] = await Promise.all([ - findRSDMember({searchFor, token, frontend}), + findRSDPerson({searchFor, token, frontend}), getORCID({searchFor}) ]) @@ -42,54 +40,3 @@ export async function searchForMember({searchFor,token,frontend=true}: return [] } } - - -// this is always frontend call -export async function findRSDMember({searchFor, token, frontend}: - { searchFor: string, token?: string, frontend?: boolean }) { - try { - let url = '/rpc/unique_team_members?limit=20' - if (frontend) { - url = '/api/v1' + url - } else { - url = `${process.env.POSTGREST_URL}` + url - } - - if (isOrcid(searchFor)) { - url = url + `&orcid=eq.${searchFor}` - } else { - url = url + `&display_name=ilike.*${searchFor}*` - } - - const resp = await fetch(url, { - method: 'GET', - headers: { - ...createJsonHeaders(token), - } - }) - - if (resp.status === 200) { - const data: SearchTeamMember[] = await resp.json() - const options: AutocompleteOption[] = data.map(item => { - return { - key: item.display_name ?? '', - label: item.display_name ?? '', - data: { - ...item, - source: 'RSD' - } - } - }) - return options - } else if (resp.status === 404) { - logger('findRSDMember ERROR: 404 Not found', 'error') - // query not found - return [] - } - logger(`findRSDMember ERROR: ${resp?.status} ${resp?.statusText}`, 'error') - return [] - } catch (e: any) { - logger(`findRSDMember: ${e?.message}`, 'error') - return [] - } -} diff --git a/frontend/components/software/AboutSection.tsx b/frontend/components/software/AboutSection.tsx index 4e5e5794d..1cbd237c1 100644 --- a/frontend/components/software/AboutSection.tsx +++ b/frontend/components/software/AboutSection.tsx @@ -33,7 +33,7 @@ export default function AboutSection({ return ( -
    +
    { expect(copyButton).toBeInTheDocument() }) - it.only('should have "Download file" button initialy disabled',()=>{ + it('should have "Download file" button initialy disabled',()=>{ // find it const downloadButton = screen.getByRole('button',{ name:'Download file' diff --git a/frontend/components/software/ContactPersonCard.tsx b/frontend/components/software/ContactPersonCard.tsx index 74b07d5f6..3df118234 100644 --- a/frontend/components/software/ContactPersonCard.tsx +++ b/frontend/components/software/ContactPersonCard.tsx @@ -1,4 +1,6 @@ // SPDX-FileCopyrightText: 2022 Dusan Mijatovic (dv4all) +// SPDX-FileCopyrightText: 2022 Ewan Cahen (Netherlands eScience Center) +// SPDX-FileCopyrightText: 2022 Netherlands eScience Center // SPDX-FileCopyrightText: 2022 dv4all // // SPDX-License-Identifier: Apache-2.0 @@ -6,9 +8,11 @@ /* eslint-disable @next/next/no-img-element */ import EmailIcon from '@mui/icons-material/Email' import Avatar from '@mui/material/Avatar' +import {getImageUrl} from '~/utils/editImage' import {Contributor} from '../../types/Contributor' import {getDisplayName, getDisplayInitials} from '../../utils/getDisplayName' +import LogoOrcid from '~/assets/logos/logo-orcid.svg' export default function ContactPersonCard({person}: { person: Contributor|null }) { @@ -23,13 +27,13 @@ export default function ContactPersonCard({person}: { person: Contributor|null } href={`mailto:${person?.email_address}`} target="_blank" rel="noreferrer" > - - Mail {person?.given_names} + + Mail {person?.given_names} ) } @@ -42,7 +46,7 @@ export default function ContactPersonCard({person}: { person: Contributor|null } {/*
    */} {person?.affiliation ?? ''} + {person?.orcid &&
    + + {person.orcid} + +
    } {renderEmail()}
    diff --git a/frontend/components/software/ContributorsList.tsx b/frontend/components/software/ContributorsList.tsx index 08ffbcc8b..5c95add9d 100644 --- a/frontend/components/software/ContributorsList.tsx +++ b/frontend/components/software/ContributorsList.tsx @@ -5,12 +5,13 @@ // // SPDX-License-Identifier: Apache-2.0 -import {Contributor} from '../../types/Contributor' +import {Person} from '../../types/Contributor' import ContributorAvatar from './ContributorAvatar' import {getDisplayName, getDisplayInitials} from '../../utils/getDisplayName' import PersonalInfo from './PersonalInfo' +import {getImageUrl} from '~/utils/editImage' -export default function ContributorsList({contributors}: { contributors: Contributor[] }) { +export default function ContributorsList({contributors}: { contributors: Person[] }) { // do not render component if no data if (contributors?.length === 0) return null @@ -19,11 +20,12 @@ export default function ContributorsList({contributors}: { contributors: Contrib
    {contributors.map(item => { const displayName = getDisplayName(item) + const avatarUrl = getImageUrl(item.avatar_id) ?? '' if (displayName) { return (
    diff --git a/frontend/components/software/ContributorsSection.tsx b/frontend/components/software/ContributorsSection.tsx index 192c58c28..03e3575c1 100644 --- a/frontend/components/software/ContributorsSection.tsx +++ b/frontend/components/software/ContributorsSection.tsx @@ -3,14 +3,14 @@ // // SPDX-License-Identifier: Apache-2.0 -import {Contributor} from '../../types/Contributor' +import {Contributor, Person} from '../../types/Contributor' import PageContainer from '../layout/PageContainer' import ContributorsList from './ContributorsList' import ContactPersonCard from './ContactPersonCard' -function clasifyContributors(contributors: Contributor[]) { - const contributorList:Contributor[] = [] - let contact: Contributor | null = null +function clasifyContributors(contributors: Person[]) { + const contributorList:Person[] = [] + let contact: Person | null = null contributors.forEach(item => { // take first contact person to be show as contact @@ -30,7 +30,7 @@ function clasifyContributors(contributors: Contributor[]) { // shared component with project page for team members export default function ContributorsSection({contributors, title='Contributors'}: - { contributors: Contributor[], title?:string }) { + { contributors: Person[], title?:string }) { // do not show section if no content if (typeof contributors == 'undefined' || contributors?.length===0) return null // clasify diff --git a/frontend/components/software/ParticipatingOrganisation.tsx b/frontend/components/software/ParticipatingOrganisation.tsx index 7678dea70..ef13b9752 100644 --- a/frontend/components/software/ParticipatingOrganisation.tsx +++ b/frontend/components/software/ParticipatingOrganisation.tsx @@ -24,12 +24,11 @@ export default function OrganisationItem({rsd_path, name, website, logo_url}: Pa // internal RSD link to organisation url = `/organisations/${rsd_path}` return ( - - - {renderLogo()} - + + {renderLogo()} ) } @@ -38,7 +37,8 @@ export default function OrganisationItem({rsd_path, name, website, logo_url}: Pa // organisation website url = website return ( - {renderLogo()} diff --git a/frontend/components/software/SoftwareCard.tsx b/frontend/components/software/SoftwareCard.tsx index 430ba9488..18eb0ef86 100644 --- a/frontend/components/software/SoftwareCard.tsx +++ b/frontend/components/software/SoftwareCard.tsx @@ -74,48 +74,48 @@ export default function SoftwareCard({href, brand_name, short_statement, is_feat } return ( - + {/* anchor tag MUST be first element after Link component */} - - ) } diff --git a/frontend/components/software/add/AddSoftwareCard.test.tsx b/frontend/components/software/add/AddSoftwareCard.test.tsx index 27c7fbb97..1e0297295 100644 --- a/frontend/components/software/add/AddSoftwareCard.test.tsx +++ b/frontend/components/software/add/AddSoftwareCard.test.tsx @@ -11,20 +11,22 @@ import AddSoftwareCard from './AddSoftwareCard' import {addConfig} from './addConfig' import {getSlugFromString} from '../../../utils/getSlugFromString' -// mock addSoftware -import * as editSoftware from '../../../utils/editSoftware' - -// mock addSoftware -const mockAddSoftware = jest.spyOn(editSoftware, 'addSoftware') - .mockImplementation((props) => Promise.resolve({status: 201, message: props})) - -// mock validSoftwareItem -const mockValidSoftwareItem = jest.spyOn(editSoftware, 'validSoftwareItem') - .mockImplementation((props) => new Promise((res, rej) => { +const mockAddSoftware = jest.fn((props)=>Promise.resolve({status: 201, message: props})) +const mockValidSoftwareItem = jest.fn((slug,token) => { + // console.log('validProjectItem...props...',slug,token) + return new Promise((res, rej) => { setTimeout(() => { res(false) - },100) - })) + }, 10) + }) +}) + +jest.mock('~/utils/editSoftware', () => { + return { + addSoftware: jest.fn((props)=> mockAddSoftware(props)), + validSoftwareItem: jest.fn((slug,token)=> mockValidSoftwareItem(slug,token)) + } +}) // mock next router const mockBack = jest.fn() diff --git a/frontend/components/software/edit/contributors/EditContributorModal.tsx b/frontend/components/software/edit/contributors/EditContributorModal.tsx index 7258fed99..5809c4ee1 100644 --- a/frontend/components/software/edit/contributors/EditContributorModal.tsx +++ b/frontend/components/software/edit/contributors/EditContributorModal.tsx @@ -5,7 +5,7 @@ // // SPDX-License-Identifier: Apache-2.0 -import {useEffect,useState} from 'react' +import {ChangeEvent, useEffect} from 'react' import { Button, Dialog, DialogActions, DialogContent, DialogTitle, useMediaQuery @@ -13,6 +13,7 @@ import { import DeleteIcon from '@mui/icons-material/Delete' import {useForm} from 'react-hook-form' +import {useSession} from '~/auth' import useSnackbar from '../../../snackbar/useSnackbar' import {Contributor} from '../../../../types/Contributor' import ControlledTextField from '../../../form/ControlledTextField' @@ -20,9 +21,11 @@ import ControlledSwitch from '../../../form/ControlledSwitch' import ContributorAvatar from '../../ContributorAvatar' import {contributorInformation as config} from '../editSoftwareConfig' import {getDisplayInitials, getDisplayName} from '../../../../utils/getDisplayName' -import logger from '../../../../utils/logger' import ControlledAffiliation from '~/components/form/ControlledAffiliation' import SubmitButtonWithListener from '~/components/form/SubmitButtonWithListener' +import {handleFileUpload} from '~/utils/handleFileUpload' +import {deleteImage, getImageUrl} from '~/utils/editImage' +import {patchContributor} from '~/utils/editContributors' type EditContributorModalProps = { open: boolean, @@ -35,14 +38,13 @@ type EditContributorModalProps = { const formId='edit-contributor-modal' export default function EditContributorModal({open, onCancel, onSubmit, contributor, pos}: EditContributorModalProps) { - const {showWarningMessage} = useSnackbar() + const {token} = useSession() + const {showWarningMessage,showErrorMessage} = useSnackbar() const smallScreen = useMediaQuery('(max-width:600px)') - const [b64Image, setB64Image]=useState() const {handleSubmit, watch, formState, reset, control, register, setValue} = useForm({ mode: 'onChange', defaultValues: { - ...contributor, - avatar_b64:null + ...contributor } }) @@ -50,6 +52,11 @@ export default function EditContributorModal({open, onCancel, onSubmit, contribu const {isValid, isDirty} = formState const formData = watch() + // console.group('EditContributorModal') + // console.log('isDirty...', isDirty) + // console.log('isValid...', isValid) + // console.groupEnd() + useEffect(() => { if (contributor) { reset(contributor) @@ -59,44 +66,82 @@ export default function EditContributorModal({open, onCancel, onSubmit, contribu function handleCancel() { // reset form reset() - // remove image upload - setB64Image(undefined) // hide onCancel() } - function handleFileUpload({target}:{target: any}) { - try { - let file = target.files[0] - if (typeof file == 'undefined') return - // check file size - if (file.size > 2097152) { - // file is to large > 2MB - showWarningMessage('The file is too large. Please select image < 2MB.') - return - } - let reader = new FileReader() - reader.onloadend = function () { - if (reader.result) { - // write to new avatar b64 - setValue('avatar_b64', reader.result as string) - setValue('avatar_mime_type', file.type,{shouldDirty: true}) - } + async function onFileUpload(e:ChangeEvent|undefined) { + if (typeof e !== 'undefined') { + const {status, message, image_b64, image_mime_type} = await handleFileUpload(e) + if (status === 200 && image_b64 && image_mime_type) { + replaceImage(image_b64, image_mime_type) + } else if (status===413) { + showWarningMessage(message) + } else { + showErrorMessage(message) } - reader.readAsDataURL(file) - } catch (e:any) { - logger(`handleFileUpload: ${e.message}`,'error') } } - function getAvatarUrl() { - if (formData?.avatar_b64 && formData?.avatar_b64?.length > 10) { - return formData?.avatar_b64 + async function replaceImage(avatar_b64:string, avatar_mime_type:string) { + if (formData.id && formData.avatar_id) { + // remove refrence to avatar first + const patch = await patchContributor({ + contributor: { + id: formData.id, + avatar_id: null + }, + token + }) + // debugger + if (patch.status !== 200) { + showErrorMessage('Failed to remove image') + return + } + // then try to remove avatar from db + // without waiting for result + const del = await deleteImage({ + id: formData.avatar_id, + token + }) + // remove id in the form too + setValue('avatar_id', null) } - if (formData?.avatar_url && formData?.avatar_url.length > 10) { - return formData?.avatar_url + // write new logo to logo_b64 + // we upload the image after submit + setValue('avatar_b64', avatar_b64) + setValue('avatar_mime_type', avatar_mime_type, {shouldDirty: true}) + } + + async function deleteAvatar() { + if (formData.id && formData.avatar_id) { + // remove reference to avatar first + const patch = await patchContributor({ + contributor: { + id: formData.id, + avatar_id: null + }, + token + }) + // debugger + if (patch.status !== 200) { + showErrorMessage('Failed to remove image') + return + } + // then try to remove avatar from db + // without waiting for result + const del = await deleteImage({ + id: formData.avatar_id, + token + }) + // update form + setValue('avatar_id', null, {shouldDirty:true,shouldValidate:true}) + } else { + // just remove uploaded image from form + // because it is not save yet to DB + setValue('avatar_b64', null) + setValue('avatar_mime_type', null, {shouldDirty: true}) } - return '' } return ( @@ -128,10 +173,10 @@ export default function EditContributorModal({open, onCancel, onSubmit, contribu {...register('software')} /> @@ -153,23 +198,15 @@ export default function EditContributorModal({open, onCancel, onSubmit, contribu id="upload-avatar-image" type="file" accept="image/*" - onChange={handleFileUpload} + onChange={onFileUpload} style={{display:'none'}} />
    diff --git a/frontend/components/software/edit/contributors/FindContributor.tsx b/frontend/components/software/edit/contributors/FindContributor.tsx index b98078196..c50d0b4f2 100644 --- a/frontend/components/software/edit/contributors/FindContributor.tsx +++ b/frontend/components/software/edit/contributors/FindContributor.tsx @@ -7,22 +7,28 @@ import {HTMLAttributes, useState} from 'react' -import {Contributor, SearchContributor} from '../../../../types/Contributor' +import {Contributor, SearchPerson} from '../../../../types/Contributor' import {searchForContributor} from '../../../../utils/editContributors' import FindContributorItem from './FindContributorItem' import {splitName} from '../../../../utils/getDisplayName' import {contributorInformation as config} from '../editSoftwareConfig' import AsyncAutocompleteSC,{AutocompleteOption} from '~/components/form/AsyncAutocompleteSC' import {isOrcid} from '~/utils/getORCID' +import {useSession} from '~/auth' export type Name = { given_names: string family_names?: string } -export default function FindContributor({onAdd, onCreate}: - { onAdd: (item: Contributor) => void, onCreate:(name:Name)=>void}) { - const [options, setOptions] = useState[]>([]) +type FindContributorProps = { + software: string, + onAdd: (item: Contributor) => void +} + +export default function FindContributor({onAdd, software}:FindContributorProps) { + const {token} = useSession() + const [options, setOptions] = useState[]>([]) const [status, setStatus] = useState<{ loading: boolean, foundFor: string | undefined @@ -35,6 +41,7 @@ export default function FindContributor({onAdd, onCreate}: setStatus({loading:true,foundFor:undefined}) const resp = await searchForContributor({ searchFor, + token, frontend:true }) // set options @@ -46,25 +53,42 @@ export default function FindContributor({onAdd, onCreate}: }) } - function addContributor(selected:AutocompleteOption) { + function addContributor(selected:AutocompleteOption) { if (selected && selected.data) { onAdd({ ...selected.data, - is_contact_person: false, - software: '', id: null, - position: null + software: '', + is_contact_person: false, + role: null, + position: null, + // RSD entries could have avatar + avatar_id: selected.data.avatar_id ?? null }) } } function createNewContributor(newInputValue: string) { const name = splitName(newInputValue) - onCreate(name) + // onCreate(name) + onAdd({ + id: null, + software, + is_contact_person: false, + ...name, + email_address: null, + affiliation: null, + role: null, + orcid: null, + avatar_id: null, + avatar_mime_type: null, + avatar_b64: null, + position: null + }) } function renderAddOption(props: HTMLAttributes, - option: AutocompleteOption) { + option: AutocompleteOption) { // if more than one option we add border at the bottom // we assume that first option is Add "new item" if (options.length > 1) { @@ -83,7 +107,7 @@ export default function FindContributor({onAdd, onCreate}: } function renderOption(props: HTMLAttributes, - option: AutocompleteOption) { + option: AutocompleteOption) { // console.log('renderOption...', option) // when value is not found option returns input prop if (option?.input) { diff --git a/frontend/components/software/edit/contributors/FindContributorItem.tsx b/frontend/components/software/edit/contributors/FindContributorItem.tsx index 3245cba56..6f677fb9e 100644 --- a/frontend/components/software/edit/contributors/FindContributorItem.tsx +++ b/frontend/components/software/edit/contributors/FindContributorItem.tsx @@ -3,10 +3,16 @@ // // SPDX-License-Identifier: Apache-2.0 +import {getImageUrl} from '~/utils/editImage' +import {getDisplayInitials, getDisplayName} from '~/utils/getDisplayName' import {AutocompleteOption} from '../../../../types/AutocompleteOptions' -import {SearchContributor} from '../../../../types/Contributor' +import {SearchPerson} from '../../../../types/Contributor' +import ContributorAvatar from '../../ContributorAvatar' -export default function FindContributorItem({option}: { option: AutocompleteOption }) { +export default function FindContributorItem({option}: { option: AutocompleteOption }) { + + const displayName = getDisplayName(option.data) + const displayInitials = getDisplayInitials(option.data) function renderSecondRow() { const {affiliation,orcid,institution} = option.data @@ -52,16 +58,23 @@ export default function FindContributorItem({option}: { option: AutocompleteOpti } return ( -
    -
    -
    - {option.label} +
    + +
    +
    +
    + {option.label} +
    + {option.data?.source} +
    +
    + {renderSecondRow()}
    - {option.data?.source} -
    -
    - {renderSecondRow()} -
    +
    ) } diff --git a/frontend/components/software/edit/contributors/GetContributorsFromDoi.tsx b/frontend/components/software/edit/contributors/GetContributorsFromDoi.tsx index 1936f600d..07498e348 100644 --- a/frontend/components/software/edit/contributors/GetContributorsFromDoi.tsx +++ b/frontend/components/software/edit/contributors/GetContributorsFromDoi.tsx @@ -10,13 +10,14 @@ import {contributorInformation as config} from '../editSoftwareConfig' import useSoftwareContext from '../useSoftwareContext' import {useState} from 'react' import {getContributorsFromDoi} from '~/utils/getInfoFromDatacite' -import {Contributor} from '~/types/Contributor' +import {Contributor, ContributorProps} from '~/types/Contributor' import {itemsNotInReferenceList} from '~/utils/itemsNotInReferenceList' -import {addContributorToDb, prepareContributorData} from '~/utils/editContributors' +import {postContributor} from '~/utils/editContributors' import {useSession} from '~/auth' import useSnackbar from '~/components/snackbar/useSnackbar' import {getDisplayName} from '~/utils/getDisplayName' import {CircularProgress} from '@mui/material' +import {getPropsFromObject} from '~/utils/getPropsFromObject' type GetContributorsFromDoiProps = { contributors: Contributor[] @@ -64,11 +65,11 @@ export default function GetContributorsFromDoi({contributors,onSetContributors}: const newContributors:Contributor[]=[] for (const c of newDoiContributors) { // prepare data - const contributor = prepareContributorData(c) + const contributor = getPropsFromObject(c, ContributorProps) pos+=1 contributor.position = contributors.length + pos // add contributor to db - const resp = await addContributorToDb({contributor, token}) + const resp = await postContributor({contributor, token}) if (resp.status === 201) { // update item in newContributors contributor.id = resp.message diff --git a/frontend/components/software/edit/contributors/SortableContributorItem.tsx b/frontend/components/software/edit/contributors/SortableContributorItem.tsx index 91511a73d..90bd3dadd 100644 --- a/frontend/components/software/edit/contributors/SortableContributorItem.tsx +++ b/frontend/components/software/edit/contributors/SortableContributorItem.tsx @@ -14,6 +14,7 @@ import {combineRoleAndAffiliation, getDisplayInitials, getDisplayName} from '~/u import SortableListItemActions from '~/components/layout/SortableListItemActions' import {Contributor} from '~/types/Contributor' import {useMediaQuery} from '@mui/material' +import {getImageUrl} from '~/utils/editImage' type SortableContributorItemProps = { pos: number, @@ -65,7 +66,7 @@ export default function SortableContributorItem({pos, item, onEdit, onDelete}: S {smallScreen ? null : diff --git a/frontend/components/software/edit/contributors/index.tsx b/frontend/components/software/edit/contributors/index.tsx index ca23f3917..d24a79c0c 100644 --- a/frontend/components/software/edit/contributors/index.tsx +++ b/frontend/components/software/edit/contributors/index.tsx @@ -11,11 +11,10 @@ import {useSession} from '~/auth' import useSnackbar from '~/components/snackbar/useSnackbar' import ContentLoader from '~/components/layout/ContentLoader' import ConfirmDeleteModal from '~/components/layout/ConfirmDeleteModal' -import {Contributor, ContributorProps} from '~/types/Contributor' +import {Contributor, ContributorProps, SaveContributor} from '~/types/Contributor' import { - addContributorToDb, deleteContributorsById, - getAvatarUrl, patchContributorPositions, - prepareContributorData, updateContributorInDb + deleteContributorsById, patchContributor, + patchContributorPositions, postContributor, } from '~/utils/editContributors' import {getDisplayName} from '~/utils/getDisplayName' import {getPropsFromObject} from '~/utils/getPropsFromObject' @@ -29,6 +28,7 @@ import GetContributorsFromDoi from './GetContributorsFromDoi' import useSoftwareContext from '../useSoftwareContext' import useSoftwareContributors from './useSoftwareContributors' import SortableContributorsList from './SortableContributorsList' +import {deleteImage, upsertImage} from '~/utils/editImage' type EditContributorModal = ModalProps & { contributor?: Contributor @@ -53,6 +53,18 @@ export default function SoftwareContributors() { ) + function hideModals() { + // hide modals + setModal({ + edit: { + open:false + }, + delete: { + open:false + } + }) + } + function updateContributorList({data, pos}: { data: Contributor, pos?: number }) { if (typeof pos === 'number') { // REPLACE existing item and sort @@ -73,24 +85,6 @@ export default function SoftwareContributors() { } } - function onCreateNewContributor(name:Name) { - const newContributor: Contributor = getPropsFromObject(name, ContributorProps) - // set defaults - newContributor.software = software?.id ?? '' - newContributor.is_contact_person = false - loadContributorIntoModal(newContributor) - } - - async function onAddContributor(item: Contributor) { - // update software id if missing - if (item.software === '' && - software?.id && - software?.id !== '') { - item.software = software?.id - } - loadContributorIntoModal(item) - } - function loadContributorIntoModal(contributor: Contributor,pos?:number) { if (contributor) { // show modal and pass data @@ -114,38 +108,55 @@ export default function SoftwareContributors() { } async function onSubmitContributor({data, pos}:{data:Contributor,pos?: number}) { - setModal({ - edit: { - open: false - }, - delete: { - open: false + // UPLOAD avatar + if (data.avatar_b64 && data.avatar_mime_type) { + // split base64 to use only encoded content + const b64data = data.avatar_b64.split(',')[1] + const upload = await upsertImage({ + data: b64data, + mime_type: data.avatar_mime_type, + token + }) + // debugger + if (upload.status === 201) { + // update data values + data.avatar_id = upload.message + } else { + showErrorMessage(`Failed to upload image. ${upload.message}`) + return } - }) + } + // ensure software id + if (!data.software && software.id) { + data.software = software.id + } + // prepare member object for save (remove helper props) + const contributor:SaveContributor = getPropsFromObject(data, ContributorProps) // if id present we update - if (data?.id) { - const resp = await updateContributorInDb({data, token}) + if (contributor?.id && typeof pos !== 'undefined') { + const resp = await patchContributor({ + contributor, + token + }) if (resp.status === 200) { - updateContributorList({data: resp.message,pos}) - // show notification - showSuccessMessage(`Updated ${getDisplayName(data)}`) + updateContributorList({data:contributor,pos}) + hideModals() } else { showErrorMessage(`Failed to update ${getDisplayName(data)}. Error: ${resp.message}`) } } else { // this is completely new contributor we need to add to DB - const contributor = prepareContributorData(data) - const resp = await addContributorToDb({contributor, token}) - + contributor.position = contributors.length + 1 + const resp = await postContributor({ + contributor, + token + }) if (resp.status === 201) { // id of created record is provided in returned in message contributor.id = resp.message - // remove avatar data - contributor.avatar_data = null - // construct url - contributor.avatar_url = getAvatarUrl(contributor) // update contributors list updateContributorList({data: contributor}) + hideModals() } else { showErrorMessage(`Failed to add ${getDisplayName(contributor)}. Error: ${resp.message}`) } @@ -168,14 +179,7 @@ export default function SoftwareContributors() { async function deleteContributor(pos?: number) { // hide modals - setModal({ - edit: { - open:false - }, - delete: { - open:false - } - }) + hideModals() // abort if not specified if (typeof pos == 'number') { const contributor = contributors[pos] @@ -191,6 +195,14 @@ export default function SoftwareContributors() { } else { showErrorMessage(`Failed to remove ${getDisplayName(contributor)}. Error: ${resp.message}`) } + // try to remove member avatar + // without waiting for result + if (contributor.avatar_id) { + const del = await deleteImage({ + id: contributor.avatar_id, + token + }) + } } else { // new contributor removeFromContributorList(pos) @@ -248,8 +260,8 @@ export default function SoftwareContributors() { subtitle={config.findContributor.subtitle} /> { software?.concept_doi && diff --git a/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx b/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx index 09086e3dd..3518e79a6 100644 --- a/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx +++ b/frontend/components/software/edit/information/AutosaveRepositoryUrl.tsx @@ -71,7 +71,7 @@ export default function AutosaveRepositoryUrl() { }) } } else if (urlError) { - debugger + // debugger setPlatform({ id: null, disabled: true, diff --git a/frontend/components/software/edit/information/AutosaveSoftwarePageStatus.tsx b/frontend/components/software/edit/information/AutosaveSoftwarePageStatus.tsx index bca85d9c2..23897bc86 100644 --- a/frontend/components/software/edit/information/AutosaveSoftwarePageStatus.tsx +++ b/frontend/components/software/edit/information/AutosaveSoftwarePageStatus.tsx @@ -43,7 +43,7 @@ export default function AutosaveSoftwarePageStatus() { Publishing software page Setting the page status to published will expose the software page to all visitors. Unpublished software can be found under - your profile + your profile page. diff --git a/frontend/components/software/edit/information/index.tsx b/frontend/components/software/edit/information/index.tsx index b652d0a77..cae1695df 100644 --- a/frontend/components/software/edit/information/index.tsx +++ b/frontend/components/software/edit/information/index.tsx @@ -77,7 +77,7 @@ export default function SoftwareInformation({slug}: {slug: string}) { {...register('id', {required:'id is required'})} /> -
    +
    diff --git a/frontend/components/software/edit/mentions/mentionForSoftwareApi.ts b/frontend/components/software/edit/mentions/mentionForSoftwareApi.ts index 2109e2623..175482997 100644 --- a/frontend/components/software/edit/mentions/mentionForSoftwareApi.ts +++ b/frontend/components/software/edit/mentions/mentionForSoftwareApi.ts @@ -141,55 +141,3 @@ export async function removeMentionForSoftware({mention, software, token}: } } } - -// OBSOLETE? -// WE decided not to allow update of mentions by rsd_user role -// Dusan 2022-10-24 -// export async function replaceMentionForSoftware({mention, software, token}: -// { mention: MentionItemProps, software: string, token: string }) { -// try { -// let resp -// // remove refference to existing mention item -// resp = await removeMentionForSoftware({ -// software, -// mention: mention.id ?? '', -// token -// }) -// if (resp.status !== 200) { -// return resp -// } -// // debugger -// // replace mention item -// resp = await replaceMentionItem({ -// mention, -// token -// }) -// if (resp.status !== 200) { -// return resp -// } -// const newMention = { -// ...resp.message -// } -// // debugger -// // create refference to new mention item -// resp = await addToMentionForSoftware({ -// software, -// mention: newMention.id, -// token -// }) -// if (resp.status !== 200) { -// return resp -// } -// // debugger -// return { -// status: 200, -// message: newMention -// } -// } catch (e: any) { -// logger(`replaceMentionForSoftware: ${e?.message}`, 'error') -// return { -// status: 500, -// message: e?.message -// } -// } -// } diff --git a/frontend/components/software/edit/organisations/EditOrganisationModal.tsx b/frontend/components/software/edit/organisations/EditOrganisationModal.tsx index dd54744f5..4ddf871c6 100644 --- a/frontend/components/software/edit/organisations/EditOrganisationModal.tsx +++ b/frontend/components/software/edit/organisations/EditOrganisationModal.tsx @@ -5,8 +5,7 @@ // // SPDX-License-Identifier: Apache-2.0 -import {useEffect} from 'react' - +import {ChangeEvent, useEffect} from 'react' import { Avatar, Button, Dialog, DialogActions, DialogContent, @@ -15,19 +14,20 @@ import { import DeleteIcon from '@mui/icons-material/Delete' import {useForm} from 'react-hook-form' +import {useSession} from '~/auth' import useSnackbar from '../../../snackbar/useSnackbar' import ControlledTextField from '../../../form/ControlledTextField' import {EditOrganisation} from '../../../../types/Organisation' import {organisationInformation as config} from '../editSoftwareConfig' -import logger from '../../../../utils/logger' -import {getUrlFromLogoId} from '../../../../utils/editOrganisation' import SubmitButtonWithListener from '~/components/form/SubmitButtonWithListener' +import {deleteImage, getImageUrl, upsertImage} from '~/utils/editImage' +import {handleFileUpload} from '~/utils/handleFileUpload' type EditOrganisationModalProps = { open: boolean, onCancel: () => void, onSubmit: ({data, pos}: { data: EditOrganisation, pos?: number }) => void, - onDeleteLogo: (logo_id:string) => void, + // onDeleteLogo: (logo_id:string) => void, organisation?: EditOrganisation, // item position in the array pos?: number @@ -35,8 +35,9 @@ type EditOrganisationModalProps = { const formId='edit-organisation-modal' -export default function EditOrganisationModal({open, onCancel, onSubmit,onDeleteLogo,organisation, pos}: EditOrganisationModalProps) { - const {showWarningMessage} = useSnackbar() +export default function EditOrganisationModal({open, onCancel, onSubmit, organisation, pos}: EditOrganisationModalProps) { + const {token} = useSession() + const {showWarningMessage,showErrorMessage} = useSnackbar() const smallScreen = useMediaQuery('(max-width:600px)') const {handleSubmit, watch, formState, reset, control, register, setValue} = useForm({ mode: 'onChange', @@ -49,6 +50,10 @@ export default function EditOrganisationModal({open, onCancel, onSubmit,onDelete const {isValid, isDirty} = formState const formData = watch() + // console.group('EditOrganisationModal') + // console.log('formData...', formData) + // console.groupEnd() + useEffect(() => { if (organisation) { reset(organisation) @@ -60,35 +65,46 @@ export default function EditOrganisationModal({open, onCancel, onSubmit,onDelete onCancel() } - function handleFileUpload({target}:{target: any}) { - try { - let file = target.files[0] - if (typeof file == 'undefined') return - // check file size - if (file.size > 2097152) { - // file is to large > 2MB - showWarningMessage('The file is too large. Please select image < 2MB.') - return - } - let reader = new FileReader() - reader.onloadend = function () { - if (reader.result) { - // write to new avatar b64 - setValue('logo_b64', reader.result as string) - setValue('logo_mime_type', file.type,{shouldDirty: true}) - } + async function onFileUpload(e:ChangeEvent|undefined) { + if (typeof e !== 'undefined') { + const {status, message, image_b64, image_mime_type} = await handleFileUpload(e) + if (status === 200 && image_b64 && image_mime_type) { + // save image + replaceLogo(image_b64,image_mime_type) + } else if (status===413) { + showWarningMessage(message) + } else { + showErrorMessage(message) } - reader.readAsDataURL(file) - } catch (e:any) { - logger(`handleFileUpload: ${e.message}`,'error') } } - function deleteLogoFromDb() { + async function replaceLogo(logo_b64:string, logo_mime_type:string) { + if (formData.logo_id) { + // remove old logo from db + const del = await deleteImage({ + id: formData.logo_id, + token + }) + setValue('logo_id', null) + } + // write new logo to logo_b64 + // we upload the image after submit + setValue('logo_b64', logo_b64) + setValue('logo_mime_type', logo_mime_type, {shouldDirty: true}) + } + + async function deleteLogo() { if (formData.logo_id) { - onDeleteLogo(formData.logo_id) + // remove old logo from db + const del = await deleteImage({ + id: formData.logo_id, + token + }) } setValue('logo_id', null) + setValue('logo_b64', null) + setValue('logo_mime_type', null, {shouldDirty: true}) } return ( @@ -125,6 +141,9 @@ export default function EditOrganisationModal({open, onCancel, onSubmit,onDelete +
    @@ -164,15 +183,7 @@ export default function EditOrganisationModal({open, onCancel, onSubmit,onDelete title="Remove image" // color='primary' disabled={!formData.logo_b64 && !formData.logo_id} - onClick={() => { - if (formData?.logo_b64) { - setValue('logo_b64', null) - } - if (formData.logo_id) { - deleteLogoFromDb() - } - setValue('logo_mime_type',null,{shouldDirty: true}) - }} + onClick={deleteLogo} > remove diff --git a/frontend/components/software/edit/organisations/SortableOrganisationItem.tsx b/frontend/components/software/edit/organisations/SortableOrganisationItem.tsx index 5d9519809..4f3016529 100644 --- a/frontend/components/software/edit/organisations/SortableOrganisationItem.tsx +++ b/frontend/components/software/edit/organisations/SortableOrganisationItem.tsx @@ -10,7 +10,7 @@ import Avatar from '@mui/material/Avatar' import BlockIcon from '@mui/icons-material/Block' import {EditOrganisation} from '../../../../types/Organisation' -import {getUrlFromLogoId} from '../../../../utils/editOrganisation' +import {getImageUrl} from '~/utils/editImage' import IconOverlay from '~/components/layout/IconOverlay' import SortableListItemActions from '~/components/layout/SortableListItemActions' import {useSortable} from '@dnd-kit/sortable' @@ -111,7 +111,7 @@ export default function SortableOrganisationsItem({organisation, pos, onEdit, on void }) { + // extract props we need for createOrganisation + const organisation = getPropsFromObject(item, columsForCreate) // create new organisation let resp = await createOrganisation({ - item, + organisation, token }) - // only 201 and 206 accepted - if ([201, 206].includes(resp.status) === false) { - // on error we return message + // only 201 accepted + if (resp.status !== 201) { + // on error we return resp status return resp } // we receive id in message - const id = resp.message - if (resp.status === 201) { + // const id = resp.message + item.id = resp.message + if (item.id) { // add this organisation to software resp = await addOrganisationToSoftware({ software, - organisation: id, + organisation: item.id, position: item.position, token }) if (resp.status === 200) { // we receive assigned status in message item.status = resp.message - // update data, remove base64 string after upload - // and create logo_id to be used as image reference - const organisation = updateDataObjectAfterSave({ - data: item, - id - }) - // update local list - setState(organisation) + // return updated item return { status: 200, - message: 'OK' + message: item } - } else { - return resp } - } else if (resp.status === 206) { - // organisation is created but the image failed - const organisation = updateDataObjectAfterSave({ - data: item, - id - }) - setState(organisation) - // we show error about failure on logo + // debugger + return resp + } else { return { - status: 206, - message: 'Failed to upload organisation logo.' + status: 400, + message: 'Organisation id is missing.' } - } else { - return resp } } diff --git a/frontend/package.json b/frontend/package.json index bbc204919..9c71d9c6f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "rsd-frontend", - "version": "1.9.1", + "version": "1.11.2", "private": true, "scripts": { "dev": "next dev", @@ -10,56 +10,56 @@ "lint": "next lint", "lint:fix": "next lint --fix", "test": "jest", - "test:watch": "jest --watch", + "test:watch": "jest --watch --detectOpenHandles", "test:coverage": "jest --coverage" }, "dependencies": { "@dnd-kit/core": "6.0.5", "@dnd-kit/modifiers": "6.0.0", "@dnd-kit/sortable": "7.0.1", - "@emotion/react": "11.10.4", + "@emotion/react": "11.10.5", "@emotion/server": "11.10.0", - "@emotion/styled": "11.10.4", - "@mui/icons-material": "5.10.3", - "@mui/material": "5.10.5", - "@tailwindcss/line-clamp": "0.4.0", - "@tailwindcss/typography": "0.5.3", + "@emotion/styled": "11.10.5", + "@mui/icons-material": "5.10.9", + "@mui/material": "5.10.12", + "@tailwindcss/line-clamp": "0.4.2", + "@tailwindcss/typography": "0.5.7", "aos": "2.3.4", "cookie": "0.5.0", "d3": "7.6.1", "jsonwebtoken": "8.5.1", - "next": "12.2.0", + "next": "13.0.2", "nprogress": "0.2.0", "react": "18.2.0", "react-dom": "18.2.0", - "react-hook-form": "7.33.1", + "react-hook-form": "7.39.1", "react-markdown": "8.0.3", "remark-breaks": "^3.0.2", "remark-gfm": "3.0.1", - "sharp": "0.31.0", + "sharp": "0.31.2", "simplebar-react": "^2.4.3" }, "devDependencies": { - "@svgr/webpack": "6.3.1", + "@svgr/webpack": "6.5.1", "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "13.4.0", "@types/aos": "3.0.4", "@types/cookie": "0.5.1", "@types/d3": "7.4.0", - "@types/jest": "29.0.2", - "@types/jsonwebtoken": "8.5.8", - "@types/node": "18.7.18", + "@types/jest": "29.2.2", + "@types/jsonwebtoken": "8.5.9", + "@types/node": "18.11.9", "@types/nprogress": "0.2.0", - "@types/react": "18.0.20", - "@types/react-dom": "18.0.6", - "autoprefixer": "10.4.7", - "eslint": "8.19.0", - "eslint-config-next": "12.2.2", - "jest": "29.0.3", - "jest-environment-jsdom": "29.0.3", - "postcss": "8.4.14", - "tailwindcss": "3.1.5", - "typescript": "4.8.3", + "@types/react": "18.0.25", + "@types/react-dom": "18.0.8", + "autoprefixer": "10.4.13", + "eslint": "8.26.0", + "eslint-config-next": "^13.0.0", + "jest": "29.2.2", + "jest-environment-jsdom": "29.2.2", + "postcss": "8.4.18", + "tailwindcss": "3.2.2", + "typescript": "4.8.4", "whatwg-fetch": "3.6.2" } } diff --git a/frontend/pages/invite/organisation/[id].tsx b/frontend/pages/invite/organisation/[id].tsx index 3df79a614..44ff46b43 100644 --- a/frontend/pages/invite/organisation/[id].tsx +++ b/frontend/pages/invite/organisation/[id].tsx @@ -41,9 +41,7 @@ export default function InviteOrganisationMaintainer({organisationInfo, error}: You are now a maintainer of {organisationInfo?.name ?? 'missing'}!   - - Open organisation page - + Open organisation page diff --git a/frontend/pages/invite/project/[id].tsx b/frontend/pages/invite/project/[id].tsx index 49fd507eb..212c3f330 100644 --- a/frontend/pages/invite/project/[id].tsx +++ b/frontend/pages/invite/project/[id].tsx @@ -45,9 +45,7 @@ export default function InviteProjectMaintainer({projectInfo, error}: You are now a maintainer of {projectInfo?.title ?? 'missing'}!   - - Open project - + Open project diff --git a/frontend/pages/invite/software/[id].tsx b/frontend/pages/invite/software/[id].tsx index 6cc3df782..8f18c7846 100644 --- a/frontend/pages/invite/software/[id].tsx +++ b/frontend/pages/invite/software/[id].tsx @@ -43,9 +43,7 @@ export default function InviteSoftwareMaintainer({softwareInfo, error}: You are now a maintainer of {softwareInfo?.brand_name ?? 'missing'}!   - - Open software - + Open software diff --git a/frontend/pages/login/failed.tsx b/frontend/pages/login/failed.tsx index faddc92d8..6eb9cd855 100644 --- a/frontend/pages/login/failed.tsx +++ b/frontend/pages/login/failed.tsx @@ -35,8 +35,8 @@ export default function LoginFailed() { {errorMessage}

    } - Return to home page - + Go home +
    ) diff --git a/frontend/pages/projects/[slug]/index.tsx b/frontend/pages/projects/[slug]/index.tsx index 108f14b23..87617c308 100644 --- a/frontend/pages/projects/[slug]/index.tsx +++ b/frontend/pages/projects/[slug]/index.tsx @@ -22,7 +22,7 @@ import { RelatedProject, ResearchDomain } from '~/types/Project' import {MentionItemProps} from '~/types/Mention' -import {Contributor} from '~/types/Contributor' +import {Person} from '~/types/Contributor' import {ProjectOrganisationProps} from '~/types/Organisation' import {SoftwareListItem} from '~/types/SoftwareTypes' import AppHeader from '~/components/AppHeader' @@ -51,7 +51,7 @@ export interface ProjectPageProps extends ScriptProps{ links: ProjectLink[], output: MentionItemProps[], impact: MentionItemProps[], - team: Contributor[], + team: Person[], relatedSoftware: SoftwareListItem[], relatedProjects: RelatedProject[] } @@ -72,7 +72,7 @@ export default function ProjectPage(props: ProjectPageProps) { if (!project?.title){ return } - // console.log('ProjectItemPage...relatedProjects...', relatedProjects) + // console.log('ProjectPage...project...', project) return ( <> {/* Page Head meta tags */} diff --git a/frontend/public/data/settings.json b/frontend/public/data/settings.json index 887b99846..7989b71b8 100644 --- a/frontend/public/data/settings.json +++ b/frontend/public/data/settings.json @@ -9,7 +9,7 @@ "url": "rsd@esciencecenter.nl", "issues_page_url": "https://github.com/research-software-directory/RSD-as-a-service/issues" }, - "login_info_url":"https://research-software-directory.github.io/documentation/getting-started.html#signing-in" + "login_info_url":"https://research-software-directory.github.io/documentation/getting-access.html" }, "links": [ { diff --git a/frontend/types/Contributor.ts b/frontend/types/Contributor.ts index f7c00c99d..8a1d904f2 100644 --- a/frontend/types/Contributor.ts +++ b/frontend/types/Contributor.ts @@ -7,51 +7,59 @@ * Table definitions in 003-create-relations-for-software.sql */ -export type NewContributor = { - software: string +export type Person = { + id: string | null is_contact_person: boolean - given_names: string - family_names: string email_address: string | null - // NOTE! added on 2022-02-11 + family_names: string + given_names: string + affiliation?: string | null + role: string | null + orcid: string | null + position: number | null + avatar_id: string | null +} + +export type PatchPerson = { + id: string | null + is_contact_person?: boolean + email_address?: string | null + family_names?: string + given_names?: string affiliation?: string | null - // ORCID delivers array of institutions - institution?: string[] | null - // NOTE! added on 2022-02-11 role?: string | null - // NOTE! added on 2022-02-11 orcid?: string | null - // NOTE! removed on 2022-02-11 - // name_suffix: string | null - // NOTE! construct url based on id and mime-type - // avatar_data: string | null - avatar_data?: string | null - avatar_mime_type?: string | null + position?: number | null + avatar_id?: string | null } +export type SaveContributor = Person & { + software: string, +} -export type Contributor = NewContributor & { - id: string | null - avatar_url?: string | null - // avatar_file?: string +export type Contributor = Person & { + software: string + // ORCID delivers array of institutions + institution?: string[] | null + // avatar image for upload is stored in this props avatar_b64?: string | null - position: number | null - // created_at?: string - // updated_at?: string + avatar_mime_type?: string | null } -export type SearchContributor = { +export type SearchPerson = { given_names: string family_names: string email_address: string | null + orcid: string | null // NOTE! added on 2022-02-11 affiliation?: string | null // ORCID delivers array of institutions institution?: string[] | null - display_name?: string | null, - orcid?: string - source: 'RSD'|'ORCID' + display_name?: string | null + source: 'RSD' | 'ORCID' + // RSD entry provides avatar + avatar_id?: string | null } export const Person = [ @@ -63,11 +71,10 @@ export const Person = [ 'affiliation', 'role', 'orcid', - 'avatar_mime_type', + 'avatar_id', 'position' ] - export const TeamMemberProps = [ ...Person, 'project' diff --git a/frontend/types/Organisation.ts b/frontend/types/Organisation.ts index 1c05818a0..1d4e03b88 100644 --- a/frontend/types/Organisation.ts +++ b/frontend/types/Organisation.ts @@ -10,9 +10,12 @@ export type Status = 'rejected_by_origin' | 'rejected_by_relation' | 'approved' export type OrganisationRole = 'participating' | 'funding' | 'hosting' export type OrganisationSource = 'RSD' | 'ROR' | 'MANUAL' -// shared organisation properies +// organisation colums used in editOrganisation.createOrganisation +// NOTE! update when type CoreOrganisationProps changes +export const columsForCreate = [ + 'parent', 'slug', 'primary_maintainer', 'name', 'ror_id', 'is_tenant', 'website', 'logo_id', +] export type CoreOrganisationProps = { - id: string | null parent: string | null slug: string | null primary_maintainer?: string | null @@ -20,15 +23,20 @@ export type CoreOrganisationProps = { ror_id: string | null is_tenant: boolean website: string | null - // about page content created by maintainer - description: string | null + logo_id: string | null } -// object for organisation -// from organisation table +// organisation colums used in editOrganisation.updateOrganisation +// NOTE! update when type Organisation changes +export const columsForUpdate = [ + 'id', + 'description', + ...columsForCreate +] export type Organisation = CoreOrganisationProps & { - // indicates image is uploaded - logo_id: string | null + id: string | null + // about page content created by maintainer + description: string | null } // adding source @@ -36,8 +44,6 @@ export type SearchOrganisation = Organisation & { source: OrganisationSource } -export type FundingOrganisation = SearchOrganisation - // extending with other props for software edit page export type EditOrganisation = SearchOrganisation & { role?: OrganisationRole, @@ -51,6 +57,19 @@ export type EditOrganisation = SearchOrganisation & { canEdit?: boolean } +export type PatchOrganisation = { + id: string + parent?: string | null + primary_maintainer?: string | null + slug?: string | null + name?: string + description?: string | null + ror_id?: string | null + website?: string | null + is_tenant?: boolean + logo_id?: string | null +} + // object for software_for_organisation export type SoftwareForOrganisation = { software: string, @@ -88,7 +107,7 @@ export type ProjectOrganisationProps = ParticipatingOrganisationProps & { role: OrganisationRole } -export type OrganisationForOverview = CoreOrganisationProps & { +export type OrganisationForOverview = Organisation & { id: string slug: string logo_id: string | null diff --git a/frontend/types/Project.ts b/frontend/types/Project.ts index 54495b815..6d30f49d1 100644 --- a/frontend/types/Project.ts +++ b/frontend/types/Project.ts @@ -3,8 +3,8 @@ // // SPDX-License-Identifier: Apache-2.0 -import {FundingOrganisation, OrganisationRole, Status} from './Organisation' -import {SearchContributor} from './Contributor' +import {SearchOrganisation, OrganisationRole, Status} from './Organisation' +import {Person, SearchPerson} from './Contributor' export type NewProject = { slug: string @@ -16,6 +16,7 @@ export type NewProject = { date_end: string | null image_caption: string | null image_contain: boolean + image_id: string | null grant_id: string | null } @@ -24,12 +25,6 @@ export type BasicProject = NewProject & { updated_at: string } -export type RawProject = BasicProject & { - image_for_project?: { - project: string - } | null -} - export type Project = BasicProject & { image_id: string | null } @@ -38,7 +33,7 @@ export type EditProject = Project & { image_b64: string | null image_mime_type: string | null url_for_project: ProjectLink[] - funding_organisations: FundingOrganisation[] + funding_organisations: SearchOrganisation[] research_domains: ResearchDomain[] | null keywords: KeywordForProject[] } @@ -55,7 +50,6 @@ export type ProjectSearchRpc = { is_published: boolean image_id: string | null keywords: string[] - // is_featured?: boolean } // object returned from api @@ -144,31 +138,20 @@ export type ResearchDomainForProject = { research_domain: string } -export type TeamMember = { - id: string | null, +export type SaveTeamMember = Person & { + project: string, +} + +export type TeamMember = Person & { project: string, - is_contact_person: boolean, - family_names: string, - given_names: string, - email_address: string | null, - affiliation?: string | null, // ORCID delivers array of institutions // selected one is moved to affiliation institution?: string[] | null, - role: string | null, - orcid?: string | null, - // base64 image in table - avatar_data?: string | null - avatar_mime_type?: string | null - // image_url to use - avatar_url?: string | null // uploaded raw image data avatar_b64?: string | null - position: number | null + avatar_mime_type?: string | null } -export type SearchTeamMember = SearchContributor - export const ProjectTableProps = [ 'id', 'slug', 'title', 'subtitle', 'is_published', 'description', 'date_start', 'date_end', 'image_caption', diff --git a/frontend/utils/dateFn.test.ts b/frontend/utils/dateFn.test.ts index cf8600241..11575be87 100644 --- a/frontend/utils/dateFn.test.ts +++ b/frontend/utils/dateFn.test.ts @@ -22,8 +22,9 @@ describe('dateFn.daysDiff',()=>{ }) it('returns 0 if date in future',()=>{ - const date = new Date('2122-11-25') - const diff = daysDiff(date) + const since = new Date() + const plus1 = new Date(since.getTime() + 1000 * 60 * 60) + const diff = daysDiff(plus1) expect(diff).toBe(0) }) diff --git a/frontend/utils/editContributors.ts b/frontend/utils/editContributors.ts index cfc740a62..60a7bdd60 100644 --- a/frontend/utils/editContributors.ts +++ b/frontend/utils/editContributors.ts @@ -9,30 +9,11 @@ * CONTRIBUTORS */ -import {AutocompleteOption} from '../types/AutocompleteOptions' -import {Contributor, ContributorProps, SearchContributor} from '../types/Contributor' -import {createJsonHeaders, extractReturnMessage, getBaseUrl} from './fetchHelpers' -import {getORCID, isOrcid} from './getORCID' -import {getPropsFromObject} from './getPropsFromObject' import logger from './logger' - -export function getAvatarUrl({id, avatar_mime_type}:{id?:string|null,avatar_mime_type?:string|null}) { - if (avatar_mime_type) { - // construct image path - // currently we use posgrest + nginx approach image/rpc/get_contributor_image?id=15c8d47f-f8f0-45ff-861c-1e57640ebd56 - return `/image/rpc/get_contributor_image?id=${id}` - } - return null -} - -export function getAvatarUrlAsBase64({avatar_mime_type,avatar_data}: - {avatar_mime_type?: string | null, avatar_data: string | null}) { - if (avatar_mime_type && avatar_data) { - // construct the image src content for base64 images - return `data:${avatar_mime_type};base64,${avatar_data}` - } - return null -} +import {Contributor, ContributorProps, PatchPerson, SaveContributor} from '../types/Contributor' +import {createJsonHeaders, extractReturnMessage, getBaseUrl} from './fetchHelpers' +import {findRSDPerson} from './findRSDPerson' +import {getORCID} from './getORCID' export async function getContributorsForSoftware({software, token, frontend}: { software: string, token?: string, frontend?: boolean }) { @@ -53,11 +34,7 @@ export async function getContributorsForSoftware({software, token, frontend}: if (resp.status === 200) { const data: Contributor[] = await resp.json() - return data.map(item => ({ - ...item, - // add avatar url based on uuid - avatar_url: getAvatarUrl(item) - })) + return data } else if (resp.status === 404) { logger(`getContributorsForSoftware: 404 [${url}]`, 'error') // query not found @@ -75,7 +52,7 @@ export async function searchForContributor({searchFor, token, frontend}: try { const [rsdContributor, orcidOptions] = await Promise.all([ - findRSDContributor({searchFor, token, frontend}), + findRSDPerson({searchFor, token, frontend}), getORCID({searchFor}) ]) @@ -92,56 +69,8 @@ export async function searchForContributor({searchFor, token, frontend}: } } -async function findRSDContributor({searchFor, token, frontend}: - { searchFor: string, token?: string, frontend?: boolean }) { - try { - let url = '/rpc/unique_contributors?limit=20' - if (frontend) { - url = '/api/v1' + url - } else { - url = `${process.env.POSTGREST_URL}` + url - } - - if (isOrcid(searchFor)) { - url = url + `&orcid=eq.${searchFor}` - } else { - url = url + `&display_name=ilike.*${searchFor}*` - } - - const resp = await fetch(url, { - method: 'GET', - headers: { - ...createJsonHeaders(token), - } - }) - - if (resp.status === 200) { - const data: SearchContributor[] = await resp.json() - const options: AutocompleteOption[] = data.map(item => { - return { - key: item.display_name ?? '', - label: item.display_name ?? '', - data: { - ...item, - source: 'RSD' - } - } - }) - return options - } else if (resp.status === 404) { - logger('findRSDContributor ERROR: 404 Not found', 'error') - // query not found - return [] - } - logger(`findRSDContributor ERROR: ${resp?.status} ${resp?.statusText}`, 'error') - return [] - } catch (e: any) { - logger(`findRSDContributor: ${e?.message}`, 'error') - return [] - } -} - -export async function addContributorToDb({contributor, token}: { contributor: Contributor, token: string }) { +export async function postContributor({contributor, token}: + { contributor: SaveContributor, token: string }) { try { const url = '/api/v1/contributor' @@ -165,7 +94,7 @@ export async function addContributorToDb({contributor, token}: { contributor: Co return extractReturnMessage(resp) } } catch (e: any) { - logger(`addContributorToDb: ${e?.message}`, 'error') + logger(`postContributor: ${e?.message}`, 'error') return { status: 500, message: e?.message @@ -173,50 +102,8 @@ export async function addContributorToDb({contributor, token}: { contributor: Co } } -export async function updateContributorInDb({data, token}: { data: Contributor, token: string }) { - - const contributor = prepareContributorData(data) - const resp = await patchContributor({contributor, token}) - - if (resp.status === 200) { - // if we uploaded new image we remove - // data and construct avatar_url - const returned = removeBase64Data(data) - // reload image to update cache - if (returned.avatar_url) await fetch(returned.avatar_url, {cache: 'reload'}) - return { - status: 200, - message: returned - } - } else { - return resp - } -} - -export function prepareContributorData(data: Contributor) { - const contributor = getPropsFromObject(data, ContributorProps) - // do we need to save new base64 image - if (data?.avatar_b64 && - data?.avatar_b64.length > 10 && - data?.avatar_mime_type !== null) { - // split base64 to use only encoded content - contributor.avatar_data = data?.avatar_b64.split(',')[1] - } - return contributor -} - -export function removeBase64Data(contributor: Contributor) { - if (contributor.avatar_b64 && - contributor?.avatar_b64.length > 10) { - // clean it from memory data - contributor.avatar_b64 = null - // and we use avatar url instead - contributor.avatar_url = getAvatarUrl(contributor) - } - return contributor -} - -export async function patchContributor({contributor, token}: { contributor: Contributor, token: string }) { +export async function patchContributor({contributor, token}: + { contributor: PatchPerson, token: string }) { try { const url = `/api/v1/contributor?id=eq.${contributor.id}` const resp = await fetch(url, { diff --git a/frontend/utils/editImage.ts b/frontend/utils/editImage.ts new file mode 100644 index 000000000..8252908bd --- /dev/null +++ b/frontend/utils/editImage.ts @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2022 Dusan Mijatovic (dv4all) +// SPDX-FileCopyrightText: 2022 dv4all +// +// SPDX-License-Identifier: Apache-2.0 + +import {createJsonHeaders, extractReturnMessage} from './fetchHelpers' +import logger from './logger' + +export async function upsertImage({data, mime_type, token}: { + data: string, mime_type: string, token: string +}) { + try { + // POST + const url = '/api/v1/image' + const resp = await fetch(url, { + method: 'POST', + headers: { + ...createJsonHeaders(token), + 'Prefer': 'resolution=merge-duplicates,return=headers-only' + }, + body: JSON.stringify({ + // project, + data, + mime_type + }) + }) + if (resp.status === 201) { + const id = resp.headers.get('location')?.split('.')[1] + if (id) { + return { + status: 201, + message: id + } + } + return { + status: 400, + message: 'Id is missing' + } + } + return extractReturnMessage(resp) + } catch (e: any) { + logger(`addImage: ${e?.message}`, 'error') + return { + status: 500, + message: e?.message + } + } +} + +export async function deleteImage({id, token}: { + id: string, token: string +}) { + try { + // POST + const url = `/api/v1/image?id=eq.${id}` + const resp = await fetch(url, { + method: 'DELETE', + headers: { + ...createJsonHeaders(token) + } + }) + return extractReturnMessage(resp) + } catch (e: any) { + logger(`deleteImage: ${e?.message}`, 'error') + return { + status: 500, + message: e?.message + } + } +} + +export function getImageUrl(uid: string|null) { + if (uid) { + return `/image/rpc/get_image?uid=${uid}` + } + return null +} diff --git a/frontend/utils/editOrganisation.ts b/frontend/utils/editOrganisation.ts index 791af17ef..6863a6f1a 100644 --- a/frontend/utils/editOrganisation.ts +++ b/frontend/utils/editOrganisation.ts @@ -9,28 +9,20 @@ import {AutocompleteOption} from '../types/AutocompleteOptions' import { + CoreOrganisationProps, EditOrganisation, Organisation, OrganisationRole, OrganisationsForSoftware, + PatchOrganisation, SearchOrganisation } from '../types/Organisation' import {createJsonHeaders, extractReturnMessage} from './fetchHelpers' -import {getPropsFromObject} from './getPropsFromObject' +import {getImageUrl} from './editImage' import {findInROR} from './getROR' import {getSlugFromString} from './getSlugFromString' import {itemsNotInReferenceList} from './itemsNotInReferenceList' import logger from './logger' -// organisation colums used in editOrganisation.createOrganisation -const columsForCreate = [ - 'parent','slug', 'primary_maintainer', 'name', 'ror_id', 'is_tenant', 'website', -] -// organisation colums used in editOrganisation.updateOrganisation -export const columsForUpdate = [ - 'id', - ...columsForCreate -] - export async function searchForOrganisation({searchFor, token, frontend}: { searchFor: string, token?: string, frontend?: boolean }) { try { @@ -150,46 +142,15 @@ export async function getParticipatingOrganisations({software, token, frontend = name: item.name, website: item.website, rsd_path: item.rsd_path, - logo_url: getUrlFromLogoId(item.logo_id) + logo_url: getImageUrl(item.logo_id) } }) return organisations } -export async function saveExistingOrganisation({item, token, pos, setState}: - {item: EditOrganisation, token: string, pos:number, setState: (item:EditOrganisation,pos:number)=>void}) { - if (!item.id) return { - status: 400, - message: 'Organisation id missing.' - } - // update existing organisation - const resp = await updateOrganisation({ - item, - token - }) - if (resp.status === 200) { - const organisation = updateDataObjectAfterSave({ - data: item, - id: item.id - }) - // update local list - setState(organisation, pos) - // return OK state - return { - status: 200, - message: 'OK' - } - } else { - // showErrorMessage(resp.message) - return resp - } -} - -export async function createOrganisation({item, token}: - {item: EditOrganisation, token: string}) { +export async function createOrganisation({organisation, token}: + { organisation: CoreOrganisationProps, token: string}) { try { - // extract only required items - const organisation = getPropsFromObject(item,columsForCreate) const url = '/api/v1/organisation' const resp = await fetch(url, { @@ -205,33 +166,11 @@ export async function createOrganisation({item, token}: // we need to return id of created record // it can be extracted from header.location const id = resp.headers.get('location')?.split('.')[1] - if (id && - item?.logo_b64 && - item?.logo_mime_type) { - const base64 = item?.logo_b64.split(',')[1] - const resp = await uploadOrganisationLogo({ - id, - data: base64, - mime_type: item.logo_mime_type, - token - }) - if (resp.status === 200) { - return { - status: 201, - message: id - } - } else { - return { - status: 206, - message: id - } - } - } else { - return { - status: 201, - message: id - } + return { + status: 201, + message: id } + // } } else { return extractReturnMessage(resp) } @@ -243,13 +182,10 @@ export async function createOrganisation({item, token}: } } -export async function updateOrganisation({item, token}: - { item: EditOrganisation, token: string }) { +export async function updateOrganisation({organisation, token}: + { organisation: Organisation, token: string }) { try { - // extract only required items - const organisation = getPropsFromObject(item, columsForUpdate) - - const url = `/api/v1/organisation?id=eq.${item.id}` + const url = `/api/v1/organisation?id=eq.${organisation.id}` const resp = await fetch(url, { method: 'PATCH', headers: { @@ -257,22 +193,6 @@ export async function updateOrganisation({item, token}: }, body: JSON.stringify(organisation) }) - - if ([200,204].includes(resp.status) && - item?.logo_b64 && - item?.logo_mime_type && - item?.id) { - const base64 = item?.logo_b64.split(',')[1] - const resp = await uploadOrganisationLogo({ - id: item.id, - data: base64, - mime_type: item.logo_mime_type, - token - }) - // fetch image to reload the cache - await fetch(`/image/rpc/get_logo?id=${item.id}`, {cache: 'reload'}) - return resp - } return extractReturnMessage(resp) } catch (e: any) { return { @@ -282,55 +202,16 @@ export async function updateOrganisation({item, token}: } } -export async function deleteOrganisation({uuid,logo_id, token}: - { uuid: string, logo_id:string|null, token: string }) { +export async function patchOrganisation({data, token}: + { data: PatchOrganisation, token: string }) { try { - - // delete logo first - if (logo_id) { - const resp = await deleteOrganisationLogo({ - id: logo_id, - token - }) - // debugger - if (resp.status !== 200) { - return resp - } - } - - // delete organisation - const url = `/api/v1/organisation?id=eq.${uuid}` + const url = `/api/v1/organisation?id=eq.${data.id}` const resp = await fetch(url, { - method: 'DELETE', + method: 'PATCH', headers: { ...createJsonHeaders(token) - } - }) - // debugger - return extractReturnMessage(resp) - } catch (e: any) { - return { - status: 500, - message: e?.message - } - } -} - -export async function uploadOrganisationLogo({id, data, mime_type, token}: - { id: string, data: string, mime_type: string, token: string }) { - try { - const url = '/api/v1/logo_for_organisation' - const resp = await fetch(url, { - method: 'POST', - headers: { - ...createJsonHeaders(token), - 'Prefer': 'resolution=merge-duplicates' }, - body: JSON.stringify({ - organisation:id, - data, - mime_type - }) + body: JSON.stringify(data) }) return extractReturnMessage(resp) } catch (e: any) { @@ -341,16 +222,18 @@ export async function uploadOrganisationLogo({id, data, mime_type, token}: } } -export async function deleteOrganisationLogo({id, token}: - { id: string, token: string }) { +export async function deleteOrganisation({uuid,logo_id, token}: + { uuid: string, logo_id:string|null, token: string }) { try { - const url = `/api/v1/logo_for_organisation?organisation=eq.${id}` + // delete organisation + const url = `/api/v1/organisation?id=eq.${uuid}` const resp = await fetch(url, { method: 'DELETE', headers: { ...createJsonHeaders(token) } }) + // debugger return extractReturnMessage(resp) } catch (e: any) { return { @@ -390,13 +273,6 @@ export async function getRsdPathForOrganisation({uuid,token,frontend = false}: } } -export function getUrlFromLogoId(logo_id: string|null|undefined) { - if (logo_id) { - return `/image/rpc/get_logo?id=${logo_id}` - } - return null -} - export function searchToEditOrganisation({item, account, position}: { item: SearchOrganisation, account?: string, position?: number }) { @@ -428,21 +304,6 @@ export function searchToEditOrganisation({item, account, position}: return addOrganisation } -export function updateDataObjectAfterSave({data, id}: - {data: EditOrganisation, id: string}) { - // update local data - if (id) data.id = id - // if base64 image is present - if (data.logo_b64) { - // it is uploaded and uses id - data.logo_id = id - // remove image strings after upload - data.logo_b64 = null - data.logo_mime_type = null - } - return data -} - type NewOrganisation = { name: string position: number diff --git a/frontend/utils/editProject.ts b/frontend/utils/editProject.ts index 4aaee6ca3..53eecd03c 100644 --- a/frontend/utils/editProject.ts +++ b/frontend/utils/editProject.ts @@ -13,8 +13,9 @@ import {createJsonHeaders, extractReturnMessage} from './fetchHelpers' import { NewProject, ProjectLink, ResearchDomainForProject } from '~/types/Project' -import {EditOrganisation, OrganisationRole, Status} from '~/types/Organisation' -import {createOrganisation, updateDataObjectAfterSave} from './editOrganisation' +import {columsForCreate, EditOrganisation, OrganisationRole, Status} from '~/types/Organisation' +import {createOrganisation} from './editOrganisation' +import {getPropsFromObject} from './getPropsFromObject' // query for software item page based on slug export async function validProjectItem(slug: string | undefined, token?: string) { @@ -77,66 +78,56 @@ export async function addProject({project, token}: } } -export async function createOrganisationAndAddToProject({project, item, session, setState, role='participating'}: - { item: EditOrganisation, project: string, session: Session, setState: (item: EditOrganisation) => void, role?: OrganisationRole}) { +/** + * Returns item with updated props on success + */ +export async function createOrganisationAndAddToProject({project, item, token, role='participating'}: + { item: EditOrganisation, project: string, token: string, role?: OrganisationRole}) { + // extract props we need for createOrganisation + const organisation = getPropsFromObject(item, columsForCreate) // create new organisation let resp = await createOrganisation({ - item, - token: session.token + organisation, + token }) - // only 201 and 206 accepted - if ([201, 206].includes(resp.status) === false) { - // on error we return message + // only 201 accepted + if (resp.status !== 201) { + // on error we return resp status return resp } // we receive id in message - const id = resp.message - if (resp.status === 201) { + // const id = resp.message + item.id = resp.message + if (item.id) { // add this organisation to software resp = await addOrganisationToProject({ project, - organisation: id, - role: 'participating', + organisation: item.id, + role, position: item.position, - session + token }) if (resp.status === 200) { // we receive assigned status in message item.status = resp.message - // update data, remove base64 string after upload - // and create logo_id to be used as image reference - const organisation = updateDataObjectAfterSave({ - data: item, - id - }) - // update local list - setState(organisation) + // return updated item return { status: 200, - message: 'OK' + message: item } - } else { - return resp } - } else if (resp.status === 206) { - // organisation is created but the image failed - const organisation = updateDataObjectAfterSave({ - data: item, - id - }) - setState(organisation) - // we show error about failure on logo + // debugger + return resp + } else { return { - status: 206, - message: 'Failed to upload organisation logo.' + status: 400, + message: 'Organisation id is missing.' } - } else { - return resp } } -export async function addOrganisationToProject({project, organisation, role, position, session}: - { project: string, organisation: string, role: OrganisationRole, position:number|null, session:Session }) { +export async function addOrganisationToProject({project, organisation, role, position, token}: + { project: string, organisation: string, role: OrganisationRole, position:number|null, token:string }) { try { // by default request status is approved const status = 'approved' @@ -145,7 +136,7 @@ export async function addOrganisationToProject({project, organisation, role, pos const resp = await fetch(url, { method: 'POST', headers: { - ...createJsonHeaders(session.token), + ...createJsonHeaders(token), }, body: JSON.stringify({ project, @@ -188,7 +179,7 @@ export async function patchProjectForOrganisation({project, organisation, data, }) return extractReturnMessage(resp) } catch (e: any) { - debugger + // debugger return { status: 500, message: e?.message @@ -417,82 +408,6 @@ export async function deleteProjectLink({id,token}:{id:string,token:string }) { } } -export async function addImage({project, data, mime_type,token}: { - project:string,data:string,mime_type:string,token:string -}) { - try { - // POST - const url = '/api/v1/image_for_project' - const resp = await fetch(url, { - method: 'POST', - headers: { - ...createJsonHeaders(token), - 'Prefer': 'resolution=merge-duplicates' - }, - body: JSON.stringify({ - project, - data, - mime_type - }) - }) - return extractReturnMessage(resp, project ?? '') - } catch (e: any) { - logger(`addImage: ${e?.message}`, 'error') - return { - status: 500, - message: e?.message - } - } -} - -export async function updateImage({project, data, mime_type, token}: { - project: string, data: string, mime_type: string, token: string -}) { - try { - // PATCH - const url = `/api/v1/image_for_project?project=eq.${project}` - const resp = await fetch(url, { - method: 'PATCH', - headers: { - ...createJsonHeaders(token) - }, - body: JSON.stringify({ - project, - data, - mime_type - }) - }) - return extractReturnMessage(resp, project ?? '') - } catch (e: any) { - logger(`updateImage: ${e?.message}`, 'error') - return { - status: 500, - message: e?.message - } - } -} - -export async function deleteImage({project,token}:{project:string,token:string}) { - try { - // DELETE - const url = `/api/v1/image_for_project?project=eq.${project}` - const resp = await fetch(url, { - method: 'DELETE', - headers: { - ...createJsonHeaders(token) - } - }) - return extractReturnMessage(resp, project ?? '') - } catch (e: any) { - logger(`deleteImage: ${e?.message}`, 'error') - return { - status: 500, - message: e?.message - } - } -} - - export async function createMaintainerLink({project,account,token}:{project:string,account:string,token:string}) { try { // POST diff --git a/frontend/utils/findRSDPerson.ts b/frontend/utils/findRSDPerson.ts new file mode 100644 index 000000000..6b3fd765e --- /dev/null +++ b/frontend/utils/findRSDPerson.ts @@ -0,0 +1,50 @@ +import {AutocompleteOption} from '~/types/AutocompleteOptions' +import {SearchPerson} from '~/types/Contributor' +import {createJsonHeaders, getBaseUrl} from './fetchHelpers' +import {isOrcid} from './getORCID' +import logger from './logger' + +export async function findRSDPerson({searchFor, token, frontend}: + { searchFor: string, token?: string, frontend?: boolean }) { + try { + // we search for all persons in RSD (contributors + team members) + let url = `${getBaseUrl()}/rpc/unique_persons?limit=20` + + if (isOrcid(searchFor)) { + url = url + `&orcid=eq.${searchFor}` + } else { + url = url + `&display_name=ilike.*${searchFor}*` + } + + const resp = await fetch(url, { + method: 'GET', + headers: { + ...createJsonHeaders(token), + } + }) + + if (resp.status === 200) { + const data: SearchPerson[] = await resp.json() + const options: AutocompleteOption[] = data.map(item => { + return { + key: item.display_name ?? '', + label: item.display_name ?? '', + data: { + ...item, + source: 'RSD' + } + } + }) + return options + } else if (resp.status === 404) { + logger('findRSDPerson ERROR: 404 Not found', 'error') + // query not found + return [] + } + logger(`findRSDPerson ERROR: ${resp?.status} ${resp?.statusText}`, 'error') + return [] + } catch (e: any) { + logger(`findRSDPerson: ${e?.message}`, 'error') + return [] + } +} diff --git a/frontend/utils/getInfoFromDatacite.test.ts b/frontend/utils/getInfoFromDatacite.test.ts index 5502edacf..9fdbb9be1 100644 --- a/frontend/utils/getInfoFromDatacite.test.ts +++ b/frontend/utils/getInfoFromDatacite.test.ts @@ -417,15 +417,17 @@ it('returns expected contributors', async () => { expect(resp).toEqual( [ { - 'affiliation': 'Example organisation', - 'email_address': '', - 'family_names': 'Doe', - 'given_names': 'John', - 'is_contact_person': false, - 'orcid': '0000-0000-0000-0000', - 'software': '0', - 'id': null, - 'position': null + affiliation: 'Example organisation', + email_address: '', + family_names: 'Doe', + given_names: 'John', + is_contact_person: false, + orcid: '0000-0000-0000-0000', + software: '0', + id: null, + position: null, + role: null, + avatar_id: null } ] ) @@ -444,7 +446,9 @@ it('returns authors and contributors (without duplicates)', async () => { is_contact_person: false, orcid: '0000-0003-4940-3444', id: null, - position: null + position: null, + role: null, + avatar_id: null }, { given_names: 'Michael', @@ -455,7 +459,9 @@ it('returns authors and contributors (without duplicates)', async () => { is_contact_person: false, orcid: '0000-0002-1179-1659', id: null, - position: null + position: null, + role: null, + avatar_id: null } ] const resp = await getContributorsFromDoi('0', 'DOI') diff --git a/frontend/utils/getInfoFromDatacite.ts b/frontend/utils/getInfoFromDatacite.ts index 29fe85448..4040a9795 100644 --- a/frontend/utils/getInfoFromDatacite.ts +++ b/frontend/utils/getInfoFromDatacite.ts @@ -230,7 +230,9 @@ export async function getContributorsFromDoi( is_contact_person: false, orcid: useOrcid, position: null, - id: null + id: null, + role: null, + avatar_id: null }) } diff --git a/frontend/utils/getORCID.ts b/frontend/utils/getORCID.ts index 50eec8eb1..f35122a7d 100644 --- a/frontend/utils/getORCID.ts +++ b/frontend/utils/getORCID.ts @@ -6,7 +6,7 @@ // SPDX-License-Identifier: Apache-2.0 import {AutocompleteOption} from '../types/AutocompleteOptions' -import {SearchContributor} from '../types/Contributor' +import {SearchPerson} from '../types/Contributor' import {createJsonHeaders} from './fetchHelpers' import {getDisplayName} from './getDisplayName' import logger from './logger' @@ -78,7 +78,7 @@ function buildSearchQuery(searchFor: string) { } -function buildAutocompleteOptions(data: OrcidRecord[]): AutocompleteOption[]{ +function buildAutocompleteOptions(data: OrcidRecord[]): AutocompleteOption[]{ if (!data) return [] const options = data.map(item => { diff --git a/frontend/utils/getProjects.ts b/frontend/utils/getProjects.ts index 1167009c5..8fb0cf0b5 100644 --- a/frontend/utils/getProjects.ts +++ b/frontend/utils/getProjects.ts @@ -9,11 +9,11 @@ import {mentionColumns, MentionForProject, MentionItemProps} from '~/types/Menti import { KeywordForProject, OrganisationsOfProject, Project, - ProjectLink, ProjectSearchRpc, RawProject, RelatedProjectForProject, + ProjectLink, ProjectSearchRpc, RelatedProjectForProject, ResearchDomain, SearchProject, TeamMember } from '~/types/Project' import {RelatedSoftwareOfProject} from '~/types/SoftwareTypes' -import {getUrlFromLogoId} from './editOrganisation' +import {getImageUrl} from './editImage' import {extractCountFromHeader} from './extractCountFromHeader' import {createJsonHeaders} from './fetchHelpers' import logger from './logger' @@ -50,20 +50,13 @@ export async function getProjectList({url, token}: { url: string, token?: string } } } -export function extractImageInfo(item: RawProject) { - if (item?.image_for_project && item?.image_for_project !== null) { - return item.image_for_project.project - } else { - return null - } -} //used by view and edit pages export async function getProjectItem({slug,token,frontend = false}: {slug: string, token: string, frontend: boolean}) { try{ // get project by slug - const query = `project?select=*,image_for_project(project)&slug=eq.${slug}` + const query = `project?slug=eq.${slug}` let url = `${process.env.POSTGREST_URL}/${query}` if (frontend) { url=`/api/v1/${query}` @@ -75,21 +68,10 @@ export async function getProjectItem({slug,token,frontend = false}: } }) if (resp.status===200){ - const rawData: RawProject[] = await resp.json() + const rawData: Project[] = await resp.json() if (rawData && rawData.length === 1) { - // extract if image is present - const image_id = extractImageInfo(rawData[0]) - // remove raw property - const raw = rawData[0] - if (raw?.image_for_project) { - delete raw.image_for_project - } - const data: Project = { - ...raw, - image_id - } // delete data.image_for_project - return data + return rawData[0] } return undefined } @@ -101,12 +83,6 @@ export async function getProjectItem({slug,token,frontend = false}: } } -export function getImageUrl(image_id:string|null) { - if (image_id) return `/image/rpc/get_project_image?id=${image_id}` - return null -} - - export async function getOrganisationsOfProject({project, token, frontend = true, roles}: { project: string, token: string, frontend?: boolean, roles?: OrganisationRole[] }) { try { @@ -140,7 +116,7 @@ export async function getOrganisations({project, token, frontend = true}: { project: string, token: string, frontend?: boolean}) { const resp = await getOrganisationsOfProject({project, token, frontend}) // filter only approved organisations - // extract only properties used + // extract only used properties const organisations = resp.filter(item => { return item.status === 'approved' }) @@ -150,7 +126,7 @@ export async function getOrganisations({project, token, frontend = true}: name: item.name, website: item.website ?? '', rsd_path: item.rsd_path, - logo_url: getUrlFromLogoId(item.logo_id), + logo_url: getImageUrl(item.logo_id), role: item.role } }) @@ -323,15 +299,6 @@ export async function getImpactForProject({project, token, frontend}: } } -export function getAvatarUrl({id, avatar_mime_type}: { id?: string | null, avatar_mime_type?: string | null }) { - if (avatar_mime_type) { - // construct image path - // currently we use posgrest + nginx approach image/rpc/get_contributor_image?id=15c8d47f-f8f0-45ff-861c-1e57640ebd56 - return `/image/rpc/get_team_member_image?id=${id}` - } - return null -} - export async function getTeamForProject({project, token, frontend}: {project: string, token?: string, frontend?: boolean}) { try { @@ -351,11 +318,7 @@ export async function getTeamForProject({project, token, frontend}: if (resp.status === 200) { const data: TeamMember[] = await resp.json() - return data.map(item => ({ - ...item, - // add avatar url based on uuid - avatar_url: getAvatarUrl(item) - })) + return data } logger(`getTeamForProject: ${resp.status} ${resp.statusText} [${url}]`, 'warn') // / query not found diff --git a/frontend/utils/handleFileUpload.ts b/frontend/utils/handleFileUpload.ts new file mode 100644 index 000000000..88fb20852 --- /dev/null +++ b/frontend/utils/handleFileUpload.ts @@ -0,0 +1,60 @@ +import logger from './logger' + +type HandleFileUploadResponse = { + status: number, + message: string, + image_b64: string|null, + image_mime_type: string|null +} + +export function handleFileUpload({target}: { target: any }): Promise{ + return new Promise((res, rej) => { + try { + if (typeof target==='undefined' || target===null) res({ + status: 400, + message: 'Target element missing', + image_b64: null, + image_mime_type: null + }) + // console.log('Upload files...',target.files) + let file = target?.files[0] ?? null + // if no file the upload is canceled + if (typeof file === 'undefined' || file === null) res({ + status: 400, + message: 'File not found / not provided', + image_b64: null, + image_mime_type: null + }) + // check file size + if (file.size > 2097152) { + res({ + status: 413, + message: 'The file is too large. Please select image < 2MB.', + image_b64: null, + image_mime_type: null + }) + } + let reader = new FileReader() + // listen to onloadend event + reader.onloadend = function () { + if (reader.result) { + res({ + status: 200, + message: 'OK', + image_b64: reader.result as string, + image_mime_type: file.type + }) + } + } + reader.readAsDataURL(file) + } catch (e: any) { + logger(`handleFileUpload: ${e.message}`, 'error') + res({ + status: 500, + message: `handleFileUpload: ${e.message}`, + image_b64: null, + image_mime_type: null + }) + } + }) +} diff --git a/frontend/utils/postgrestUrl.test.ts b/frontend/utils/postgrestUrl.test.ts index 412ce99bc..2141d1847 100644 --- a/frontend/utils/postgrestUrl.test.ts +++ b/frontend/utils/postgrestUrl.test.ts @@ -4,7 +4,11 @@ // SPDX-License-Identifier: Apache-2.0 import {rowsPerPageOptions} from '~/config/pagination' -import {baseQueryString, PostgrestParams, projectListUrl, softwareListUrl, softwareUrl, ssrOrganisationUrl, ssrProjectsUrl} from './postgrestUrl' +import { + baseQueryString, PostgrestParams, + projectListUrl, softwareListUrl, + ssrSoftwareUrl, ssrOrganisationUrl, ssrProjectsUrl +} from './postgrestUrl' describe('baseQueryString', () => { @@ -40,10 +44,10 @@ describe('baseQueryString', () => { }) -describe('softwareUrl', () => { +describe('ssrSoftwareUrl', () => { it('returns software page url with stringified and encoded keywords query parameters', () => { const expectUrl = '/software?&keywords=%5B%22filter-1%22%2C%22filter-2%22%5D&page=0&rows=12' - const url = softwareUrl({ + const url = ssrSoftwareUrl({ keywords: ['filter-1', 'filter-2'] }) expect(url).toEqual(expectUrl) @@ -51,7 +55,7 @@ describe('softwareUrl', () => { it('returns software page url with search param and page 10', () => { const expectUrl = '/software?search=test-search-item&page=10&rows=12' - const url = softwareUrl({ + const url = ssrSoftwareUrl({ search: 'test-search-item', page: 10 }) @@ -72,7 +76,7 @@ describe('softwareListUrl', () => { it('returns postgrest endpoint url with search params', () => { const baseUrl = 'http://test-base-url' // if you change search value then change expectedUrl values too - const expectUrl = `${baseUrl}/rpc/software_search?limit=12&offset=0&or=(brand_name.ilike.*test-search*, short_statement.ilike.*test-search*)` + const expectUrl = `${baseUrl}/rpc/software_search?limit=12&offset=0&or=(brand_name.ilike.*test-search*,short_statement.ilike.*test-search*,keywords_text.ilike.*test-search*)` const url = softwareListUrl({ baseUrl, // if you change search value then change expectedUrl values too @@ -93,7 +97,7 @@ describe('softwareListUrl', () => { }) }) -describe.only('ssrProjectsUrl', () => { +describe('ssrProjectsUrl', () => { it('returns projects page url with stringified and encoded keywords query parameters', () => { const expectUrl = '/projects?&keywords=%5B%22filter-1%22%2C%22filter-2%22%5D&page=0&rows=12' const url = ssrProjectsUrl({ @@ -125,7 +129,7 @@ describe('projectListUrl', () => { it('returns postgrest endpoint url with search params', () => { const baseUrl = 'http://test-base-url' // if you change search value then change expectedUrl values too - const expectUrl = `${baseUrl}/rpc/project_search?limit=12&offset=0&or=(title.ilike.*test-search*,subtitle.ilike.*test-search*)` + const expectUrl = `${baseUrl}/rpc/project_search?limit=12&offset=0&or=(title.ilike.*test-search*,subtitle.ilike.*test-search*,keywords_text.ilike.*test-search*,research_domain_text.ilike.*test-search*)` const url = projectListUrl({ baseUrl, // if you change search value then change expectedUrl values too diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 98cb74776..c3797c347 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -22,38 +22,38 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.1.tgz#72d647b4ff6a4f82878d184613353af1dd0290f9" - integrity sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg== +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" + integrity sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.5": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.1.tgz#c8fa615c5e88e272564ace3d42fbc8b17bfeb22b" - integrity sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw== +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.19.6": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.2.tgz#8dc9b1620a673f92d3624bd926dc49a52cf25b92" + integrity sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g== dependencies: "@ampproject/remapping" "^2.1.0" "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" - "@babel/helper-compilation-targets" "^7.19.1" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.1" + "@babel/generator" "^7.20.2" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-module-transforms" "^7.20.2" + "@babel/helpers" "^7.20.1" + "@babel/parser" "^7.20.2" "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.1" - "@babel/types" "^7.19.0" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.2" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@^7.19.0", "@babel/generator@^7.7.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a" - integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg== +"@babel/generator@^7.20.1", "@babel/generator@^7.20.2", "@babel/generator@^7.7.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.2.tgz#c2e89e22613a039285c1e7b749e2cd0b30b9a481" + integrity sha512-SD75PMIK6i9H8G/tfGvB4KKl4Nw6Ssos9nGgYwxbgyTP0iX/Z55DveoH86rmUB/YHTQQ+ZC0F7xxaY8l2OF44Q== dependencies: - "@babel/types" "^7.19.0" + "@babel/types" "^7.20.2" "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" @@ -72,27 +72,27 @@ "@babel/helper-explode-assignable-expression" "^7.18.6" "@babel/types" "^7.18.9" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz#7f630911d83b408b76fe584831c98e5395d7a17c" - integrity sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg== +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" + integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== dependencies: - "@babel/compat-data" "^7.19.1" + "@babel/compat-data" "^7.20.0" "@babel/helper-validator-option" "^7.18.6" browserslist "^4.21.3" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b" - integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz#3c08a5b5417c7f07b5cf3dfb6dc79cbec682e8c2" + integrity sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-function-name" "^7.19.0" "@babel/helper-member-expression-to-functions" "^7.18.9" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-replace-supers" "^7.19.1" "@babel/helper-split-export-declaration" "^7.18.6" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": @@ -156,19 +156,19 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" - integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.6", "@babel/helper-module-transforms@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" + integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.2" "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" @@ -177,10 +177,10 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" - integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== "@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": version "7.18.9" @@ -192,7 +192,7 @@ "@babel/helper-wrap-function" "^7.18.9" "@babel/types" "^7.18.9" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== @@ -203,19 +203,19 @@ "@babel/traverse" "^7.19.1" "@babel/types" "^7.19.0" -"@babel/helper-simple-access@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" - integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== +"@babel/helper-simple-access@^7.19.4", "@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.20.2" "@babel/helper-skip-transparent-expression-wrappers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" - integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" + integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== dependencies: - "@babel/types" "^7.18.9" + "@babel/types" "^7.20.0" "@babel/helper-split-export-declaration@^7.18.6": version "7.18.6" @@ -224,12 +224,12 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-string-parser@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" - integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== -"@babel/helper-validator-identifier@^7.18.6": +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== @@ -249,14 +249,14 @@ "@babel/traverse" "^7.19.0" "@babel/types" "^7.19.0" -"@babel/helpers@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" - integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== +"@babel/helpers@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.1.tgz#2ab7a0fcb0a03b5bf76629196ed63c2d7311f4c9" + integrity sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg== dependencies: "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.0" "@babel/highlight@^7.18.6": version "7.18.6" @@ -267,10 +267,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.1.tgz#6f6d6c2e621aad19a92544cc217ed13f1aac5b4c" - integrity sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.1", "@babel/parser@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.2.tgz#9aeb9b92f64412b5f81064d46f6a1ac0881337f4" + integrity sha512-afk318kh2uKbo7BEj2QtEi8HVCGrwHUffrYDy7dgVcSa2j9lY3LDjPzcyGdpX7xgm35aWqvciZJ4WKmdF/SxYg== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" @@ -288,10 +288,10 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" "@babel/plugin-proposal-optional-chaining" "^7.18.9" -"@babel/plugin-proposal-async-generator-functions@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7" - integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q== +"@babel/plugin-proposal-async-generator-functions@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz#352f02baa5d69f4e7529bdac39aaa02d41146af9" + integrity sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g== dependencies: "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-plugin-utils" "^7.19.0" @@ -363,16 +363,16 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" - integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== +"@babel/plugin-proposal-object-rest-spread@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz#a556f59d555f06961df1e572bb5eca864c84022d" + integrity sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ== dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/compat-data" "^7.20.1" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-parameters" "^7.20.1" "@babel/plugin-proposal-optional-catch-binding@^7.18.6": version "7.18.6" @@ -459,12 +459,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" - integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== +"@babel/plugin-syntax-import-assertions@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" + integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" @@ -543,12 +543,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.18.6", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" - integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== +"@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" + integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-transform-arrow-functions@^7.18.6": version "7.18.6" @@ -573,25 +573,25 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoping@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" - integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== +"@babel/plugin-transform-block-scoping@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz#f59b1767e6385c663fd0bce655db6ca9c8b236ed" + integrity sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" -"@babel/plugin-transform-classes@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" - integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A== +"@babel/plugin-transform-classes@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz#c0033cf1916ccf78202d04be4281d161f6709bb2" + integrity sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.19.0" + "@babel/helper-compilation-targets" "^7.20.0" "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-function-name" "^7.19.0" "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.19.1" "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" @@ -602,12 +602,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-destructuring@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" - integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== +"@babel/plugin-transform-destructuring@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz#c23741cfa44ddd35f5e53896e88c75331b8b2792" + integrity sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.18.6" @@ -662,35 +662,32 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-modules-amd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" - integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== +"@babel/plugin-transform-modules-amd@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz#aca391801ae55d19c4d8d2ebfeaa33df5f2a2cbd" + integrity sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.19.6" + "@babel/helper-plugin-utils" "^7.19.0" -"@babel/plugin-transform-modules-commonjs@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" - integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== +"@babel/plugin-transform-modules-commonjs@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz#25b32feef24df8038fc1ec56038917eacb0b730c" + integrity sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-module-transforms" "^7.19.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-simple-access" "^7.19.4" -"@babel/plugin-transform-modules-systemjs@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f" - integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A== +"@babel/plugin-transform-modules-systemjs@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz#59e2a84064b5736a4471b1aa7b13d4431d327e0d" + integrity sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ== dependencies: "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.0" + "@babel/helper-module-transforms" "^7.19.6" "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-validator-identifier" "^7.19.1" "@babel/plugin-transform-modules-umd@^7.18.6": version "7.18.6" @@ -723,12 +720,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/helper-replace-supers" "^7.18.6" -"@babel/plugin-transform-parameters@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" - integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== +"@babel/plugin-transform-parameters@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.1.tgz#9a5aa370fdcce36f110455e9369db7afca0f9eeb" + integrity sha512-nDvKLrAvl+kf6BOy1UJ3MGwzzfTMgppxwiD2Jb4LO3xjYyZq30oQzDNJbCQpMdG9+j2IXHoiMrw5Cm/L6ZoxXQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-transform-property-literals@^7.18.6": version "7.18.6" @@ -737,12 +734,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-react-constant-elements@^7.17.12": - version "7.18.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.18.12.tgz#edf3bec47eb98f14e84fa0af137fcc6aad8e0443" - integrity sha512-Q99U9/ttiu+LMnRU8psd23HhvwXmKWDQIpocm0JKaICcZHnw+mdQbHm6xnSy7dOl8I5PELakYtNBubNQlBXbZw== +"@babel/plugin-transform-react-constant-elements@^7.18.12": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.20.2.tgz#3f02c784e0b711970d7d8ccc96c4359d64e27ac7" + integrity sha512-KS/G8YI8uwMGKErLFOHS/ekhqdHhpEloxs43NecQHVgo2QuQSyJhGIY1fL8UGl9wy5ItVwwoUL4YxVqsplGq2g== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-transform-react-display-name@^7.18.6": version "7.18.6" @@ -829,13 +826,13 @@ "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-typescript@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz#adcf180a041dcbd29257ad31b0c65d4de531ce8d" - integrity sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ== + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz#91515527b376fc122ba83b13d70b01af8fe98f3f" + integrity sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag== dependencies: - "@babel/helper-create-class-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-typescript" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.20.2" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-typescript" "^7.20.0" "@babel/plugin-transform-unicode-escapes@^7.18.10": version "7.18.10" @@ -852,18 +849,18 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/preset-env@^7.18.2": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.1.tgz#9f04c916f9c0205a48ebe5cc1be7768eb1983f67" - integrity sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA== +"@babel/preset-env@^7.19.4": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506" + integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== dependencies: - "@babel/compat-data" "^7.19.1" - "@babel/helper-compilation-targets" "^7.19.1" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/compat-data" "^7.20.1" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-validator-option" "^7.18.6" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.19.1" + "@babel/plugin-proposal-async-generator-functions" "^7.20.1" "@babel/plugin-proposal-class-properties" "^7.18.6" "@babel/plugin-proposal-class-static-block" "^7.18.6" "@babel/plugin-proposal-dynamic-import" "^7.18.6" @@ -872,7 +869,7 @@ "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.18.9" + "@babel/plugin-proposal-object-rest-spread" "^7.20.2" "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" "@babel/plugin-proposal-optional-chaining" "^7.18.9" "@babel/plugin-proposal-private-methods" "^7.18.6" @@ -883,7 +880,7 @@ "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.18.6" + "@babel/plugin-syntax-import-assertions" "^7.20.0" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -896,10 +893,10 @@ "@babel/plugin-transform-arrow-functions" "^7.18.6" "@babel/plugin-transform-async-to-generator" "^7.18.6" "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.18.9" - "@babel/plugin-transform-classes" "^7.19.0" + "@babel/plugin-transform-block-scoping" "^7.20.2" + "@babel/plugin-transform-classes" "^7.20.2" "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.18.13" + "@babel/plugin-transform-destructuring" "^7.20.2" "@babel/plugin-transform-dotall-regex" "^7.18.6" "@babel/plugin-transform-duplicate-keys" "^7.18.9" "@babel/plugin-transform-exponentiation-operator" "^7.18.6" @@ -907,14 +904,14 @@ "@babel/plugin-transform-function-name" "^7.18.9" "@babel/plugin-transform-literals" "^7.18.9" "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.18.6" - "@babel/plugin-transform-modules-commonjs" "^7.18.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.0" + "@babel/plugin-transform-modules-amd" "^7.19.6" + "@babel/plugin-transform-modules-commonjs" "^7.19.6" + "@babel/plugin-transform-modules-systemjs" "^7.19.6" "@babel/plugin-transform-modules-umd" "^7.18.6" "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" "@babel/plugin-transform-new-target" "^7.18.6" "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-parameters" "^7.20.1" "@babel/plugin-transform-property-literals" "^7.18.6" "@babel/plugin-transform-regenerator" "^7.18.6" "@babel/plugin-transform-reserved-words" "^7.18.6" @@ -926,7 +923,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.18.10" "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.19.0" + "@babel/types" "^7.20.2" babel-plugin-polyfill-corejs2 "^0.3.3" babel-plugin-polyfill-corejs3 "^0.6.0" babel-plugin-polyfill-regenerator "^0.4.1" @@ -944,7 +941,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.17.12": +"@babel/preset-react@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== @@ -956,7 +953,7 @@ "@babel/plugin-transform-react-jsx-development" "^7.18.6" "@babel/plugin-transform-react-pure-annotations" "^7.18.6" -"@babel/preset-typescript@^7.17.12": +"@babel/preset-typescript@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== @@ -966,19 +963,19 @@ "@babel/plugin-transform-typescript" "^7.18.6" "@babel/runtime-corejs3@^7.10.2": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.19.1.tgz#f0cbbe7edda7c4109cd253bb1dee99aba4594ad9" - integrity sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g== + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.20.1.tgz#d0775a49bb5fba77e42cbb7276c9955c7b05af8d" + integrity sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg== dependencies: core-js-pure "^3.25.1" - regenerator-runtime "^0.13.4" + regenerator-runtime "^0.13.10" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" - integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== +"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.19.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.1.tgz#1148bb33ab252b165a06698fde7576092a78b4a9" + integrity sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg== dependencies: - regenerator-runtime "^0.13.4" + regenerator-runtime "^0.13.10" "@babel/template@^7.18.10", "@babel/template@^7.3.3": version "7.18.10" @@ -989,29 +986,29 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" -"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.7.2": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.1.tgz#0fafe100a8c2a603b4718b1d9bf2568d1d193347" - integrity sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA== +"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1", "@babel/traverse@^7.7.2": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.1.tgz#9b15ccbf882f6d107eeeecf263fbcdd208777ec8" + integrity sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA== dependencies: "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.0" + "@babel/generator" "^7.20.1" "@babel/helper-environment-visitor" "^7.18.9" "@babel/helper-function-name" "^7.19.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.19.1" - "@babel/types" "^7.19.0" + "@babel/parser" "^7.20.1" + "@babel/types" "^7.20.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.4", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600" - integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA== +"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.2.tgz#67ac09266606190f496322dbaff360fdaa5e7842" + integrity sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog== dependencies: - "@babel/helper-string-parser" "^7.18.10" - "@babel/helper-validator-identifier" "^7.18.6" + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -1058,34 +1055,34 @@ dependencies: tslib "^2.0.0" -"@emotion/babel-plugin@^11.10.0": - version "11.10.2" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz#879db80ba622b3f6076917a1e6f648b1c7d008c7" - integrity sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA== +"@emotion/babel-plugin@^11.10.5": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz#65fa6e1790ddc9e23cc22658a4c5dea423c55c3c" + integrity sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/plugin-syntax-jsx" "^7.17.12" "@babel/runtime" "^7.18.3" "@emotion/hash" "^0.9.0" "@emotion/memoize" "^0.8.0" - "@emotion/serialize" "^1.1.0" + "@emotion/serialize" "^1.1.1" babel-plugin-macros "^3.1.0" convert-source-map "^1.5.0" escape-string-regexp "^4.0.0" find-root "^1.1.0" source-map "^0.5.7" - stylis "4.0.13" + stylis "4.1.3" -"@emotion/cache@^11.10.0", "@emotion/cache@^11.10.3": - version "11.10.3" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.3.tgz#c4f67904fad10c945fea5165c3a5a0583c164b87" - integrity sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ== +"@emotion/cache@^11.10.3", "@emotion/cache@^11.10.5": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.5.tgz#c142da9351f94e47527ed458f7bbbbe40bb13c12" + integrity sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA== dependencies: "@emotion/memoize" "^0.8.0" - "@emotion/sheet" "^1.2.0" + "@emotion/sheet" "^1.2.1" "@emotion/utils" "^1.2.0" "@emotion/weak-memoize" "^0.3.0" - stylis "4.0.13" + stylis "4.1.3" "@emotion/hash@^0.9.0": version "0.9.0" @@ -1104,24 +1101,24 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== -"@emotion/react@11.10.4": - version "11.10.4" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.4.tgz#9dc6bccbda5d70ff68fdb204746c0e8b13a79199" - integrity sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA== +"@emotion/react@11.10.5": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.5.tgz#95fff612a5de1efa9c0d535384d3cfa115fe175d" + integrity sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.0" - "@emotion/cache" "^11.10.0" - "@emotion/serialize" "^1.1.0" + "@emotion/babel-plugin" "^11.10.5" + "@emotion/cache" "^11.10.5" + "@emotion/serialize" "^1.1.1" "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" "@emotion/utils" "^1.2.0" "@emotion/weak-memoize" "^0.3.0" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.0.tgz#b1f97b1011b09346a40e9796c37a3397b4ea8ea8" - integrity sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA== +"@emotion/serialize@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0" + integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA== dependencies: "@emotion/hash" "^0.9.0" "@emotion/memoize" "^0.8.0" @@ -1139,20 +1136,20 @@ multipipe "^1.0.2" through "^2.3.8" -"@emotion/sheet@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.0.tgz#771b1987855839e214fc1741bde43089397f7be5" - integrity sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w== +"@emotion/sheet@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" + integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== -"@emotion/styled@11.10.4": - version "11.10.4" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.4.tgz#e93f84a4d54003c2acbde178c3f97b421fce1cd4" - integrity sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ== +"@emotion/styled@11.10.5": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.5.tgz#1fe7bf941b0909802cb826457e362444e7e96a79" + integrity sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.0" + "@emotion/babel-plugin" "^11.10.5" "@emotion/is-prop-valid" "^1.2.0" - "@emotion/serialize" "^1.1.0" + "@emotion/serialize" "^1.1.1" "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" "@emotion/utils" "^1.2.0" @@ -1176,10 +1173,10 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== -"@eslint/eslintrc@^1.3.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356" - integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ== +"@eslint/eslintrc@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" + integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1191,14 +1188,19 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== +"@humanwhocodes/config-array@^0.11.6": + version "0.11.7" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" + integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" @@ -1221,109 +1223,109 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.0.3.tgz#a222ab87e399317a89db88a58eaec289519e807a" - integrity sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg== +"@jest/console@^29.2.1": + version "29.2.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.2.1.tgz#5f2c62dcdd5ce66e94b6d6729e021758bceea090" + integrity sha512-MF8Adcw+WPLZGBiNxn76DOuczG3BhODTcMlDCA4+cFi41OkaY/lyI0XUUhi73F88Y+7IHoGmD80pN5CtxQUdSw== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.0.3" - jest-util "^29.0.3" + jest-message-util "^29.2.1" + jest-util "^29.2.1" slash "^3.0.0" -"@jest/core@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.0.3.tgz#ba22a9cbd0c7ba36e04292e2093c547bf53ec1fd" - integrity sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ== +"@jest/core@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.2.2.tgz#207aa8973d9de8769f9518732bc5f781efc3ffa7" + integrity sha512-susVl8o2KYLcZhhkvSB+b7xX575CX3TmSvxfeDjpRko7KmT89rHkXj6XkDkNpSeFMBzIENw5qIchO9HC9Sem+A== dependencies: - "@jest/console" "^29.0.3" - "@jest/reporters" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.2.1" + "@jest/reporters" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^29.0.0" - jest-config "^29.0.3" - jest-haste-map "^29.0.3" - jest-message-util "^29.0.3" - jest-regex-util "^29.0.0" - jest-resolve "^29.0.3" - jest-resolve-dependencies "^29.0.3" - jest-runner "^29.0.3" - jest-runtime "^29.0.3" - jest-snapshot "^29.0.3" - jest-util "^29.0.3" - jest-validate "^29.0.3" - jest-watcher "^29.0.3" + jest-changed-files "^29.2.0" + jest-config "^29.2.2" + jest-haste-map "^29.2.1" + jest-message-util "^29.2.1" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.2" + jest-resolve-dependencies "^29.2.2" + jest-runner "^29.2.2" + jest-runtime "^29.2.2" + jest-snapshot "^29.2.2" + jest-util "^29.2.1" + jest-validate "^29.2.2" + jest-watcher "^29.2.2" micromatch "^4.0.4" - pretty-format "^29.0.3" + pretty-format "^29.2.1" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.0.3.tgz#7745ec30a954e828e8cc6df6a13280d3b51d8f35" - integrity sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA== +"@jest/environment@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.2.2.tgz#481e729048d42e87d04842c38aa4d09c507f53b0" + integrity sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A== dependencies: - "@jest/fake-timers" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/fake-timers" "^29.2.2" + "@jest/types" "^29.2.1" "@types/node" "*" - jest-mock "^29.0.3" + jest-mock "^29.2.2" -"@jest/expect-utils@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.0.3.tgz#f5bb86f5565bf2dacfca31ccbd887684936045b2" - integrity sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q== +"@jest/expect-utils@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.2.2.tgz#460a5b5a3caf84d4feb2668677393dd66ff98665" + integrity sha512-vwnVmrVhTmGgQzyvcpze08br91OL61t9O0lJMDyb6Y/D8EKQ9V7rGUb/p7PDt0GPzK0zFYqXWFo4EO2legXmkg== dependencies: - jest-get-type "^29.0.0" + jest-get-type "^29.2.0" -"@jest/expect@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.0.3.tgz#9dc7c46354eeb7a348d73881fba6402f5fdb2c30" - integrity sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ== +"@jest/expect@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.2.2.tgz#81edbd33afbde7795ca07ff6b4753d15205032e4" + integrity sha512-zwblIZnrIVt8z/SiEeJ7Q9wKKuB+/GS4yZe9zw7gMqfGf4C5hBLGrVyxu1SzDbVSqyMSlprKl3WL1r80cBNkgg== dependencies: - expect "^29.0.3" - jest-snapshot "^29.0.3" + expect "^29.2.2" + jest-snapshot "^29.2.2" -"@jest/fake-timers@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.0.3.tgz#ad5432639b715d45a86a75c47fd75019bc36b22c" - integrity sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ== +"@jest/fake-timers@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.2.2.tgz#d8332e6e3cfa99cde4bc87d04a17d6b699deb340" + integrity sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" "@sinonjs/fake-timers" "^9.1.2" "@types/node" "*" - jest-message-util "^29.0.3" - jest-mock "^29.0.3" - jest-util "^29.0.3" + jest-message-util "^29.2.1" + jest-mock "^29.2.2" + jest-util "^29.2.1" -"@jest/globals@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.0.3.tgz#681950c430fdc13ff9aa89b2d8d572ac0e4a1bf5" - integrity sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w== +"@jest/globals@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.2.2.tgz#205ff1e795aa774301c2c0ba0be182558471b845" + integrity sha512-/nt+5YMh65kYcfBhj38B3Hm0Trk4IsuMXNDGKE/swp36yydBWfz3OXkLqkSvoAtPW8IJMSJDFCbTM2oj5SNprw== dependencies: - "@jest/environment" "^29.0.3" - "@jest/expect" "^29.0.3" - "@jest/types" "^29.0.3" - jest-mock "^29.0.3" + "@jest/environment" "^29.2.2" + "@jest/expect" "^29.2.2" + "@jest/types" "^29.2.1" + jest-mock "^29.2.2" -"@jest/reporters@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.0.3.tgz#735f110e08b44b38729d8dbbb74063bdf5aba8a5" - integrity sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw== +"@jest/reporters@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.2.2.tgz#69b395f79c3a97ce969ce05ccf1a482e5d6de290" + integrity sha512-AzjL2rl2zJC0njIzcooBvjA4sJjvdoq98sDuuNs4aNugtLPSQ+91nysGKRF0uY1to5k0MdGMdOBggUsPqvBcpA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.2.1" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" "@jridgewell/trace-mapping" "^0.3.15" "@types/node" "*" chalk "^4.0.0" @@ -1336,13 +1338,12 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.0.3" - jest-util "^29.0.3" - jest-worker "^29.0.3" + jest-message-util "^29.2.1" + jest-util "^29.2.1" + jest-worker "^29.2.1" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" - terminal-link "^2.0.0" v8-to-istanbul "^9.0.1" "@jest/schemas@^29.0.0": @@ -1352,60 +1353,60 @@ dependencies: "@sinclair/typebox" "^0.24.1" -"@jest/source-map@^29.0.0": - version "29.0.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.0.0.tgz#f8d1518298089f8ae624e442bbb6eb870ee7783c" - integrity sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ== +"@jest/source-map@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" + integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== dependencies: "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.0.3.tgz#b03d8ef4c58be84cd5d5d3b24d4b4c8cabbf2746" - integrity sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg== +"@jest/test-result@^29.2.1": + version "29.2.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.2.1.tgz#f42dbf7b9ae465d0a93eee6131473b8bb3bd2edb" + integrity sha512-lS4+H+VkhbX6z64tZP7PAUwPqhwj3kbuEHcaLuaBuB+riyaX7oa1txe0tXgrFj5hRWvZKvqO7LZDlNWeJ7VTPA== dependencies: - "@jest/console" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.2.1" + "@jest/types" "^29.2.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.0.3.tgz#0681061ad21fb8e293b49c4fdf7e631ca79240ba" - integrity sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ== +"@jest/test-sequencer@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.2.2.tgz#4ac7487b237e517a1f55e7866fb5553f6e0168b9" + integrity sha512-Cuc1znc1pl4v9REgmmLf0jBd3Y65UXJpioGYtMr/JNpQEIGEzkmHhy6W6DLbSsXeUA13TDzymPv0ZGZ9jH3eIw== dependencies: - "@jest/test-result" "^29.0.3" + "@jest/test-result" "^29.2.1" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" + jest-haste-map "^29.2.1" slash "^3.0.0" -"@jest/transform@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.0.3.tgz#9eb1fed2072a0354f190569807d1250572fb0970" - integrity sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg== +"@jest/transform@^29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.2.2.tgz#dfc03fc092b31ffea0c55917728e75bfcf8b5de6" + integrity sha512-aPe6rrletyuEIt2axxgdtxljmzH8O/nrov4byy6pDw9S8inIrTV+2PnjyP/oFHMSynzGxJ2s6OHowBNMXp/Jzg== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" "@jridgewell/trace-mapping" "^0.3.15" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" - jest-regex-util "^29.0.0" - jest-util "^29.0.3" + jest-haste-map "^29.2.1" + jest-regex-util "^29.2.0" + jest-util "^29.2.1" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" write-file-atomic "^4.0.1" -"@jest/types@^29.0.3": - version "29.0.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.0.3.tgz#0be78fdddb1a35aeb2041074e55b860561c8ef63" - integrity sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A== +"@jest/types@^29.2.1": + version "29.2.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.2.1.tgz#ec9c683094d4eb754e41e2119d8bdaef01cf6da0" + integrity sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw== dependencies: "@jest/schemas" "^29.0.0" "@types/istanbul-lib-coverage" "^2.0.0" @@ -1431,7 +1432,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -1441,99 +1442,99 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" "@juggle/resize-observer@^3.3.1": version "3.4.0" resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60" integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== -"@mui/base@5.0.0-alpha.97": - version "5.0.0-alpha.97" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.97.tgz#bd12db4ed3bb1dbc2879944bbdb68b559641b02a" - integrity sha512-gvo0hOg/tBzfJ3eDQOGAPBJJU+qTWd0e5zBEMFIkT1ekJqXx14JtIHvheOFU17y9iDciYE256Q8g+tj6a1dcBA== +"@mui/base@5.0.0-alpha.104": + version "5.0.0-alpha.104" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.104.tgz#1792e962dd782f1fa434f4aa7bab5410ed946644" + integrity sha512-tQPxZTzfYMwxYfKhEwufbTfdLpNjFdW7bXq6dK0j8651AAyZL4M8wynWUQ98hH1362R26mZFhVxHB2UD9t7VuA== dependencies: - "@babel/runtime" "^7.18.9" + "@babel/runtime" "^7.19.0" "@emotion/is-prop-valid" "^1.2.0" "@mui/types" "^7.2.0" - "@mui/utils" "^5.10.3" + "@mui/utils" "^5.10.9" "@popperjs/core" "^2.11.6" clsx "^1.2.1" prop-types "^15.8.1" react-is "^18.2.0" -"@mui/core-downloads-tracker@^5.10.5": - version "5.10.5" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.5.tgz#be060b633268b124d27474e772e506bb3f39ca51" - integrity sha512-sZYg85rQdlgDYU3V4WcT2Dl+k+y2wYqN04aUvVkFksRR0j81sj6KmfXx4842HJQcq5rjzcTvh4N+yv66XR/9fA== +"@mui/core-downloads-tracker@^5.10.12": + version "5.10.12" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.12.tgz#ff36abc5f4aac3c762d116e12ab51c2688d93da1" + integrity sha512-cR8lOS606G++iVHR8I6ySgMAEiPoA3DxO/nLeqiv7w7d1707kvKoV4/7SWjh4ui+kHb052xlf/G196q2EKx31w== -"@mui/icons-material@5.10.3": - version "5.10.3" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.10.3.tgz#33bd1d973c4727ab55d02928fc8973b7f16fff55" - integrity sha512-o0kbUlsWCBtCE0wP33cGKbyryCh7kpm2EECYMPDmWrLhbA+HUODXIdhiTFS26szp2xXo9HY1lEx0ufeJ+tddYw== +"@mui/icons-material@5.10.9": + version "5.10.9" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.10.9.tgz#f9522c49797caf30146acc576e37ecb4f95bbc38" + integrity sha512-sqClXdEM39WKQJOQ0ZCPTptaZgqwibhj2EFV9N0v7BU1PO8y4OcX/a2wIQHn4fNuDjIZktJIBrmU23h7aqlGgg== dependencies: - "@babel/runtime" "^7.18.9" + "@babel/runtime" "^7.19.0" -"@mui/material@5.10.5": - version "5.10.5" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.10.5.tgz#390f95f346e5459d8df43f5e749b2310cefba96d" - integrity sha512-VFMadvfA6jqx5DCk2xoBl4bAGyzgmmubJIuB7fUWUZBwYIYL5Ea9SsoFpt5kawA6O2feuj69alDN2fhxPw1MeQ== +"@mui/material@5.10.12": + version "5.10.12" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.10.12.tgz#1e97bb4bdfdfde136c1acbfb6ab16991de1e8677" + integrity sha512-rG9ZTkG9qUwujyAY1I+uQAa9pkGdsWY3KN+wvS/6H6ZbYIA06QRwmig6ySC6LbeB3WL/I/1ngwJqWX7nfINSbA== dependencies: - "@babel/runtime" "^7.18.9" - "@mui/base" "5.0.0-alpha.97" - "@mui/core-downloads-tracker" "^5.10.5" - "@mui/system" "^5.10.5" + "@babel/runtime" "^7.19.0" + "@mui/base" "5.0.0-alpha.104" + "@mui/core-downloads-tracker" "^5.10.12" + "@mui/system" "^5.10.12" "@mui/types" "^7.2.0" - "@mui/utils" "^5.10.3" + "@mui/utils" "^5.10.9" "@types/react-transition-group" "^4.4.5" clsx "^1.2.1" - csstype "^3.1.0" + csstype "^3.1.1" prop-types "^15.8.1" react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.10.3": - version "5.10.3" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.10.3.tgz#7325eef3e480caaaa2d866b9057943ec4fbcb8ce" - integrity sha512-LCYIKlkGz2BTSng2BFzzwSJBRZbChIUri2x2Nh8ryk2B1Ho7zpvE7ex6y39LlStG2Frf92NFC/V4YQbmMAjD5A== +"@mui/private-theming@^5.10.9": + version "5.10.9" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.10.9.tgz#c427bfa736455703975cdb108dbde6a174ba7971" + integrity sha512-BN7/CnsVPVyBaQpDTij4uV2xGYHHHhOgpdxeYLlIu+TqnsVM7wUeF+37kXvHovxM6xmL5qoaVUD98gDC0IZnHg== dependencies: - "@babel/runtime" "^7.18.9" - "@mui/utils" "^5.10.3" + "@babel/runtime" "^7.19.0" + "@mui/utils" "^5.10.9" prop-types "^15.8.1" -"@mui/styled-engine@^5.10.5": - version "5.10.5" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.10.5.tgz#8ce4197e887a69119aea056320aad5812025ceb4" - integrity sha512-6U6tTdf+H1OsjgcFoY12gYPR+qqZ1WHGGIahK5V7JhMkMUgH7ozyiNi8s1LzmwrUlAz1hAAhuO5nBYXku3wWvw== +"@mui/styled-engine@^5.10.8": + version "5.10.8" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.10.8.tgz#2db411e4278f06f70ccb6b5cd56ace67109513f6" + integrity sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw== dependencies: - "@babel/runtime" "^7.18.9" + "@babel/runtime" "^7.19.0" "@emotion/cache" "^11.10.3" - csstype "^3.1.0" + csstype "^3.1.1" prop-types "^15.8.1" -"@mui/system@^5.10.5": - version "5.10.5" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.10.5.tgz#b0c8494aa9230fb3b8e33c4aee05207925519569" - integrity sha512-GUPiDVZTKp9yH3FVeLSIw3Bqsyl7qLxtAK1ZiZmC8e+zdH7bcnZZXvWK3vPIbx35ZyhQpvAOWQFpiF9TjdA77w== +"@mui/system@^5.10.12": + version "5.10.12" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.10.12.tgz#fd97a6fd75995038c1c34e9c5b6eb4ff9b9eee56" + integrity sha512-9DcN3hF2KTTTpZ0K5Tn20B+Tz7tIqDmJLk1M6P0CYoAGUN/xrcF/6dn1zZ829rxE5tmauoDUekTfomrvPsvlSQ== dependencies: - "@babel/runtime" "^7.18.9" - "@mui/private-theming" "^5.10.3" - "@mui/styled-engine" "^5.10.5" + "@babel/runtime" "^7.19.0" + "@mui/private-theming" "^5.10.9" + "@mui/styled-engine" "^5.10.8" "@mui/types" "^7.2.0" - "@mui/utils" "^5.10.3" + "@mui/utils" "^5.10.9" clsx "^1.2.1" - csstype "^3.1.0" + csstype "^3.1.1" prop-types "^15.8.1" "@mui/types@^7.2.0": @@ -1541,93 +1542,93 @@ resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.0.tgz#91380c2d42420f51f404120f7a9270eadd6f5c23" integrity sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA== -"@mui/utils@^5.10.3": - version "5.10.3" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.10.3.tgz#ce2a96f31de2a5e717f507b5383dbabbddbc4dfc" - integrity sha512-4jXMDPfx6bpMVuheLaOpKTjpzw39ogAZLeaLj5+RJec3E37/hAZMYjURfblLfTWMMoGoqkY03mNsZaEwNobBow== +"@mui/utils@^5.10.9": + version "5.10.9" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.10.9.tgz#9dc455f9230f43eeb81d96a9a4bdb3855bb9ea39" + integrity sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA== dependencies: - "@babel/runtime" "^7.18.9" + "@babel/runtime" "^7.19.0" "@types/prop-types" "^15.7.5" "@types/react-is" "^16.7.1 || ^17.0.0" prop-types "^15.8.1" react-is "^18.2.0" -"@next/env@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/env/-/env-12.2.0.tgz#17ce2d9f5532b677829840037e06f208b7eed66b" - integrity sha512-/FCkDpL/8SodJEXvx/DYNlOD5ijTtkozf4PPulYPtkPOJaMPpBSOkzmsta4fnrnbdH6eZjbwbiXFdr6gSQCV4w== +"@next/env@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.0.2.tgz#5fbd7b4146175ae406edfb4a38b62de8c880c09d" + integrity sha512-Qb6WPuRriGIQ19qd6NBxpcrFOfj8ziN7l9eZUfwff5gl4zLXluqtuZPddYZM/oWjN53ZYcuRXzL+oowKyJeYtA== -"@next/eslint-plugin-next@12.2.2": - version "12.2.2" - resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-12.2.2.tgz#b4a22c06b6454068b54cc44502168d90fbb29a6d" - integrity sha512-XOi0WzJhGH3Lk51SkSu9eZxF+IY1ZZhWcJTIGBycAbWU877IQa6+6KxMATWCOs7c+bmp6Sd8KywXJaDRxzu0JA== +"@next/eslint-plugin-next@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-13.0.2.tgz#89fe2144b37896f926e2bd9bed675396f1f697ce" + integrity sha512-W+fIIIaFU7Kct7Okx91C7XDRGolv/w2RUenX2yZFeeNVcuVzDIKUcNmckrYbYcwrNQUSXmtwrs3g8xwast0YtA== dependencies: glob "7.1.7" -"@next/swc-android-arm-eabi@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.0.tgz#f116756e668b267de84b76f068d267a12f18eb22" - integrity sha512-hbneH8DNRB2x0Nf5fPCYoL8a0osvdTCe4pvOc9Rv5CpDsoOlf8BWBs2OWpeP0U2BktGvIsuUhmISmdYYGyrvTw== - -"@next/swc-android-arm64@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.2.0.tgz#cbd9e329cef386271d4e746c08416b5d69342c24" - integrity sha512-1eEk91JHjczcJomxJ8X0XaUeNcp5Lx1U2Ic7j15ouJ83oRX+3GIslOuabW2oPkSgXbHkThMClhirKpvG98kwZg== - -"@next/swc-darwin-arm64@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.0.tgz#3473889157ba70b30ccdd4f59c46232d841744e2" - integrity sha512-x5U5gJd7ZvrEtTFnBld9O2bUlX8opu7mIQUqRzj7KeWzBwPhrIzTTsQXAiNqsaMuaRPvyHBVW/5d/6g6+89Y8g== - -"@next/swc-darwin-x64@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.0.tgz#b25198c3ef4c906000af49e4787a757965f760bb" - integrity sha512-iwMNFsrAPjfedjKDv9AXPAV16PWIomP3qw/FfPaxkDVRbUls7BNdofBLzkQmqxqWh93WrawLwaqyXpJuAaiwJA== - -"@next/swc-freebsd-x64@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.0.tgz#78e2213f8b703be0fef23a49507779b4a9842929" - integrity sha512-gRiAw8g3Akf6niTDLEm1Emfa7jXDjvaAj/crDO8hKASKA4Y1fS4kbi/tyWw5VtoFI4mUzRmCPmZ8eL0tBSG58A== - -"@next/swc-linux-arm-gnueabihf@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.0.tgz#80a4baf0ba699357e7420e2dea998908dcef5055" - integrity sha512-/TJZkxaIpeEwnXh6A40trgwd40C5+LJroLUOEQwMOJdavLl62PjCA6dGl1pgooWLCIb5YdBQ0EG4ylzvLwS2+Q== - -"@next/swc-linux-arm64-gnu@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.0.tgz#134a42ddea804d6bf04761607f774432c3126de6" - integrity sha512-++WAB4ElXCSOKG9H8r4ENF8EaV+w0QkrpjehmryFkQXmt5juVXz+nKDVlCRMwJU7A1O0Mie82XyEoOrf6Np1pA== - -"@next/swc-linux-arm64-musl@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.0.tgz#c781ac642ad35e0578d8a8d19c638b0f31c1a334" - integrity sha512-XrqkHi/VglEn5zs2CYK6ofJGQySrd+Lr4YdmfJ7IhsCnMKkQY1ma9Hv5THwhZVof3e+6oFHrQ9bWrw9K4WTjFA== - -"@next/swc-linux-x64-gnu@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.0.tgz#0e2235a59429eadd40ac8880aec18acdbc172a31" - integrity sha512-MyhHbAKVjpn065WzRbqpLu2krj4kHLi6RITQdD1ee+uxq9r2yg5Qe02l24NxKW+1/lkmpusl4Y5Lks7rBiJn4w== - -"@next/swc-linux-x64-musl@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.0.tgz#b0a10db0d9e16f079429588a58f71fa3c3d46178" - integrity sha512-Tz1tJZ5egE0S/UqCd5V6ZPJsdSzv/8aa7FkwFmIJ9neLS8/00za+OY5pq470iZQbPrkTwpKzmfTTIPRVD5iqDg== - -"@next/swc-win32-arm64-msvc@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.0.tgz#3063f850c9db7b774c69e9be74ad59986cf6fc34" - integrity sha512-0iRO/CPMCdCYUzuH6wXLnsfJX1ykBX4emOOvH0qIgtiZM0nVYbF8lkEyY2ph4XcsurpinS+ziWuYCXVqrOSqiw== - -"@next/swc-win32-ia32-msvc@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.0.tgz#001bbadf3d2cf006c4991f728d1d23e4d5c0e7cc" - integrity sha512-8A26RJVcJHwIKm8xo/qk2ePRquJ6WCI2keV2qOW/Qm+ZXrPXHMIWPYABae/nKN243YFBNyPiHytjX37VrcpUhg== - -"@next/swc-win32-x64-msvc@12.2.0": - version "12.2.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.0.tgz#9f66664f9122ca555b96a5f2fc6e2af677bf801b" - integrity sha512-OI14ozFLThEV3ey6jE47zrzSTV/6eIMsvbwozo+XfdWqOPwQ7X00YkRx4GVMKMC0rM44oGS2gmwMKYpe4EblnA== +"@next/swc-android-arm-eabi@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.2.tgz#66669b8aab5062f554b8e9905d855679aabf0342" + integrity sha512-X54UQCTFyOGnJP//Z71dPPlp4BCYcQL2ncikKXQcPzVpqPs4C3m+tKC8ivBNH6edAXkppwsLRz1/yQwgSZ9Swg== + +"@next/swc-android-arm64@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-13.0.2.tgz#c0641d30525e0fb22bf1e2baf6c461d2d9e52f1a" + integrity sha512-1P00Kv8uKaLubqo7JzPrTqgFAzSOmfb8iwqJrOb9in5IvTRtNGlkR4hU0sXzqbQNM/+SaYxze6Z5ry1IDyb/cQ== + +"@next/swc-darwin-arm64@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.2.tgz#d7e01a33393e83456dbfdc41446bb8a923968ff7" + integrity sha512-1zGIOkInkOLRv0QQGZ+3wffYsyKI4vIy62LYTvDWUn7TAYqnmXwougp9NSLqDeagLwgsv2URrykyAFixA/YqxA== + +"@next/swc-darwin-x64@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.2.tgz#d4a3fbe51edf871a675d89a7afdc78174d1e5841" + integrity sha512-ECDAjoMP1Y90cARaelS6X+k6BQx+MikAYJ8f/eaJrLur44NIOYc9HA/dgcTp5jenguY4yT8V+HCquLjAVle6fA== + +"@next/swc-freebsd-x64@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.0.2.tgz#1b54c3f38d3b36f86663a8dfcc81ea05e01f5172" + integrity sha512-2DcL/ofQdBnQX3IoI9sjlIAyLCD1oZoUBuhrhWbejvBQjutWrI0JTEv9uG69WcxWhVMm3BCsjv8GK2/68OKp7A== + +"@next/swc-linux-arm-gnueabihf@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.0.2.tgz#18495cff32c0b2182cfbf677614219d7072214da" + integrity sha512-Y3OQF1CSBSWW2vGkmvOIuOUNqOq8qX7f1ZpcKUVWP3/Uq++DZmVi9d18lgnSe1I3QFqc+nXWyun9ljsN83j0sw== + +"@next/swc-linux-arm64-gnu@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.0.2.tgz#5fb2563651166c3c6f32bf9e2f9cc6a16a9ef783" + integrity sha512-mNyzwsFF6kwZYEjnGicx9ksDZYEZvyzEc1BtCu8vdZi/v8UeixQwCiAT6FyYX9uxMPEkzk8qiU0t0u9gvltsKw== + +"@next/swc-linux-arm64-musl@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.0.2.tgz#b9f33c5e17cfe04aa5769b717284cf80865761e6" + integrity sha512-M6SdYjWgRrY3tJBxz0663zCRPTu5BRONmxlftKWWHv9LjAJ59neTLaGj4rp0A08DkJglZIoCkLOzLrzST6TGag== + +"@next/swc-linux-x64-gnu@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.0.2.tgz#29efcc2fd0122689d7e06c5b6b0883fe495db2bf" + integrity sha512-pi63RoxvG4ES1KS06Zpm0MATVIXTs/TIbLbdckeLoM40u1d3mQl/+hSSrLRSxzc2OtyL8fh92sM4gkJrQXAMAw== + +"@next/swc-linux-x64-musl@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.0.2.tgz#d68fdf6eefc57813fa91559c7089b49d6131ecab" + integrity sha512-9Pv91gfYnDONgjtRm78n64b/c54+azeHtlnqBLTnIFWSMBDRl1/WDkhKWIj3fBGPLimtK7Tko3ULR3og9RRUPw== + +"@next/swc-win32-arm64-msvc@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.0.2.tgz#acdcb3023045f60cca510f659a2349895e6405bd" + integrity sha512-Nvewe6YZaizAkGHHprbMkYqQulBjZCHKBGKeFPwoPtOA+a2Qi4pZzc/qXFyC5/2A6Z0mr2U1zg9rd04WBYMwBw== + +"@next/swc-win32-ia32-msvc@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.0.2.tgz#a78ee9211471768febac9df915c2a8dbbcd05e41" + integrity sha512-ZUBYGZw5G3QrqDpRq1EWi3aHmvPZM8ijK5TFL6UbH16cYQ0JpANmuG2P66KB93Qe/lWWzbeAZk/tj1XqwoCuPA== + +"@next/swc-win32-x64-msvc@13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.2.tgz#e86c2de910cd68a17974db5556d4588737412c68" + integrity sha512-fA9uW1dm7C0mEYGcKlbmLcVm2sKcye+1kPxh2cM4jVR+kQQMtHWsjIzeSpe2grQLSDan06z4n6hbr8b1c3hA8w== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -1642,7 +1643,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -1661,14 +1662,14 @@ integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== "@sinclair/typebox@^0.24.1": - version "0.24.41" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.41.tgz#45470b8bae32a28f1e0501066d0bacbd8b772804" - integrity sha512-TJCgQurls4FipFvHeC+gfAzb+GGstL0TDwYJKQVtTeSvJIznWzP7g3bAd5gEBlr8+bIxqnWS9VGVWREDhmE8jA== + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== "@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + version "1.8.4" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.4.tgz#d1f2d80f1bd0f2520873f161588bd9b7f8567120" + integrity sha512-RpmQdHVo8hCEHDVpO39zToS9jOhR6nw+/lQAzRNq9ErrGV9IeHM71XCn68svVl/euFeVW6BWX4p35gkhbOcSIQ== dependencies: type-detect "4.0.8" @@ -1679,135 +1680,138 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@svgr/babel-plugin-add-jsx-attribute@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.3.1.tgz#b9a5d84902be75a05ede92e70b338d28ab63fa74" - integrity sha512-jDBKArXYO1u0B1dmd2Nf8Oy6aTF5vLDfLoO9Oon/GLkqZ/NiggYWZA+a2HpUMH4ITwNqS3z43k8LWApB8S583w== - -"@svgr/babel-plugin-remove-jsx-attribute@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.3.1.tgz#4877995452efc997b36777abe1fde9705ef78e8b" - integrity sha512-dQzyJ4prwjcFd929T43Z8vSYiTlTu8eafV40Z2gO7zy/SV5GT+ogxRJRBIKWomPBOiaVXFg3jY4S5hyEN3IBjQ== - -"@svgr/babel-plugin-remove-jsx-empty-expression@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.3.1.tgz#2d67a0e92904c9be149a5b22d3a3797ce4d7b514" - integrity sha512-HBOUc1XwSU67fU26V5Sfb8MQsT0HvUyxru7d0oBJ4rA2s4HW3PhyAPC7fV/mdsSGpAvOdd8Wpvkjsr0fWPUO7A== - -"@svgr/babel-plugin-replace-jsx-attribute-value@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.3.1.tgz#306f5247139c53af70d1778f2719647c747998ee" - integrity sha512-C12e6aN4BXAolRrI601gPn5MDFCRHO7C4TM8Kks+rDtl8eEq+NN1sak0eAzJu363x3TmHXdZn7+Efd2nr9I5dA== - -"@svgr/babel-plugin-svg-dynamic-title@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.3.1.tgz#6ce26d34cbc93eb81737ef528528907c292e7aa2" - integrity sha512-6NU55Mmh3M5u2CfCCt6TX29/pPneutrkJnnDCHbKZnjukZmmgUAZLtZ2g6ZoSPdarowaQmAiBRgAHqHmG0vuqA== - -"@svgr/babel-plugin-svg-em-dimensions@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.3.1.tgz#5ade2a724b290873c30529d1d8cd23523856287a" - integrity sha512-HV1NGHYTTe1vCNKlBgq/gKuCSfaRlKcHIADn7P8w8U3Zvujdw1rmusutghJ1pZJV7pDt3Gt8ws+SVrqHnBO/Qw== - -"@svgr/babel-plugin-transform-react-native-svg@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.3.1.tgz#d654f509d692c3a09dfb475757a44bd9f6ad7ddf" - integrity sha512-2wZhSHvTolFNeKDAN/ZmIeSz2O9JSw72XD+o2bNp2QAaWqa8KGpn5Yk5WHso6xqfSAiRzAE+GXlsrBO4UP9LLw== - -"@svgr/babel-plugin-transform-svg-component@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.3.1.tgz#21a285dbffdce9567c437ebf0d081bf9210807e6" - integrity sha512-cZ8Tr6ZAWNUFfDeCKn/pGi976iWSkS8ijmEYKosP+6ktdZ7lW9HVLHojyusPw3w0j8PI4VBeWAXAmi/2G7owxw== - -"@svgr/babel-preset@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.3.1.tgz#8bd1ead79637d395e9362b01dd37cfd59702e152" - integrity sha512-tQtWtzuMMQ3opH7je+MpwfuRA1Hf3cKdSgTtAYwOBDfmhabP7rcTfBi3E7V3MuwJNy/Y02/7/RutvwS1W4Qv9g== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^6.3.1" - "@svgr/babel-plugin-remove-jsx-attribute" "^6.3.1" - "@svgr/babel-plugin-remove-jsx-empty-expression" "^6.3.1" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.3.1" - "@svgr/babel-plugin-svg-dynamic-title" "^6.3.1" - "@svgr/babel-plugin-svg-em-dimensions" "^6.3.1" - "@svgr/babel-plugin-transform-react-native-svg" "^6.3.1" - "@svgr/babel-plugin-transform-svg-component" "^6.3.1" - -"@svgr/core@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.3.1.tgz#752adf49d8d5473b15d76ca741961de093f715bd" - integrity sha512-Sm3/7OdXbQreemf9aO25keerZSbnKMpGEfmH90EyYpj1e8wMD4TuwJIb3THDSgRMWk1kYJfSRulELBy4gVgZUA== - dependencies: - "@svgr/plugin-jsx" "^6.3.1" +"@svgr/babel-plugin-add-jsx-attribute@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz#74a5d648bd0347bda99d82409d87b8ca80b9a1ba" + integrity sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ== + +"@svgr/babel-plugin-remove-jsx-attribute@*": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.5.0.tgz#652bfd4ed0a0699843585cda96faeb09d6e1306e" + integrity sha512-8zYdkym7qNyfXpWvu4yq46k41pyNM9SOstoWhKlm+IfdCE1DdnRKeMUPsWIEO/DEkaWxJ8T9esNdG3QwQ93jBA== + +"@svgr/babel-plugin-remove-jsx-empty-expression@*": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.5.0.tgz#4b78994ab7d39032c729903fc2dd5c0fa4565cb8" + integrity sha512-NFdxMq3xA42Kb1UbzCVxplUc0iqSyM9X8kopImvFnB+uSDdzIHOdbs1op8ofAvVRtbg4oZiyRl3fTYeKcOe9Iw== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz#fb9d22ea26d2bc5e0a44b763d4c46d5d3f596c60" + integrity sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg== + +"@svgr/babel-plugin-svg-dynamic-title@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz#01b2024a2b53ffaa5efceaa0bf3e1d5a4c520ce4" + integrity sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw== + +"@svgr/babel-plugin-svg-em-dimensions@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz#dd3fa9f5b24eb4f93bcf121c3d40ff5facecb217" + integrity sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA== + +"@svgr/babel-plugin-transform-react-native-svg@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz#1d8e945a03df65b601551097d8f5e34351d3d305" + integrity sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg== + +"@svgr/babel-plugin-transform-svg-component@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz#48620b9e590e25ff95a80f811544218d27f8a250" + integrity sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ== + +"@svgr/babel-preset@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.5.1.tgz#b90de7979c8843c5c580c7e2ec71f024b49eb828" + integrity sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^6.5.1" + "@svgr/babel-plugin-remove-jsx-attribute" "*" + "@svgr/babel-plugin-remove-jsx-empty-expression" "*" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.5.1" + "@svgr/babel-plugin-svg-dynamic-title" "^6.5.1" + "@svgr/babel-plugin-svg-em-dimensions" "^6.5.1" + "@svgr/babel-plugin-transform-react-native-svg" "^6.5.1" + "@svgr/babel-plugin-transform-svg-component" "^6.5.1" + +"@svgr/core@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.5.1.tgz#d3e8aa9dbe3fbd747f9ee4282c1c77a27410488a" + integrity sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw== + dependencies: + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/plugin-jsx" "^6.5.1" camelcase "^6.2.0" cosmiconfig "^7.0.1" -"@svgr/hast-util-to-babel-ast@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.3.1.tgz#59614e24d2a4a28010e02089213b3448d905769d" - integrity sha512-NgyCbiTQIwe3wHe/VWOUjyxmpUmsrBjdoIxKpXt3Nqc3TN30BpJG22OxBvVzsAh9jqep0w0/h8Ywvdk3D9niNQ== +"@svgr/hast-util-to-babel-ast@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz#81800bd09b5bcdb968bf6ee7c863d2288fdb80d2" + integrity sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw== dependencies: - "@babel/types" "^7.18.4" - entities "^4.3.0" + "@babel/types" "^7.20.0" + entities "^4.4.0" -"@svgr/plugin-jsx@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.3.1.tgz#de7b2de824296b836d6b874d498377896e367f50" - integrity sha512-r9+0mYG3hD4nNtUgsTXWGYJomv/bNd7kC16zvsM70I/bGeoCi/3lhTmYqeN6ChWX317OtQCSZZbH4wq9WwoXbw== +"@svgr/plugin-jsx@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz#0e30d1878e771ca753c94e69581c7971542a7072" + integrity sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw== dependencies: - "@babel/core" "^7.18.5" - "@svgr/babel-preset" "^6.3.1" - "@svgr/hast-util-to-babel-ast" "^6.3.1" + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/hast-util-to-babel-ast" "^6.5.1" svg-parser "^2.0.4" -"@svgr/plugin-svgo@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.3.1.tgz#3c1ff2efaed10e5c5d35a6cae7bacaedc18b5d4a" - integrity sha512-yJIjTDKPYqzFVjmsbH5EdIwEsmKxjxdXSGJVLeUgwZOZPAkNQmD1v7LDbOdOKbR44FG8465Du+zWPdbYGnbMbw== +"@svgr/plugin-svgo@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz#0f91910e988fc0b842f88e0960c2862e022abe84" + integrity sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ== dependencies: cosmiconfig "^7.0.1" deepmerge "^4.2.2" svgo "^2.8.0" -"@svgr/webpack@6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.3.1.tgz#001d03236ebb03bf47c0a4b92d5423e05095ebe6" - integrity sha512-eODxwIUShLxSMaRjzJtrj9wg89D75JLczvWg9SaB5W+OtVTkiC1vdGd8+t+pf5fTlBOy4RRXAq7x1E3DUl3D0A== - dependencies: - "@babel/core" "^7.18.5" - "@babel/plugin-transform-react-constant-elements" "^7.17.12" - "@babel/preset-env" "^7.18.2" - "@babel/preset-react" "^7.17.12" - "@babel/preset-typescript" "^7.17.12" - "@svgr/core" "^6.3.1" - "@svgr/plugin-jsx" "^6.3.1" - "@svgr/plugin-svgo" "^6.3.1" - -"@swc/helpers@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.2.tgz#ed1f6997ffbc22396665d9ba74e2a5c0a2d782f8" - integrity sha512-556Az0VX7WR6UdoTn4htt/l3zPQ7bsQWK+HqdG4swV7beUCxo/BqmvbOpUkTIm/9ih86LIf1qsUnywNL3obGHw== +"@svgr/webpack@6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.5.1.tgz#ecf027814fc1cb2decc29dc92f39c3cf691e40e8" + integrity sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA== + dependencies: + "@babel/core" "^7.19.6" + "@babel/plugin-transform-react-constant-elements" "^7.18.12" + "@babel/preset-env" "^7.19.4" + "@babel/preset-react" "^7.18.6" + "@babel/preset-typescript" "^7.18.6" + "@svgr/core" "^6.5.1" + "@svgr/plugin-jsx" "^6.5.1" + "@svgr/plugin-svgo" "^6.5.1" + +"@swc/helpers@0.4.11": + version "0.4.11" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.11.tgz#db23a376761b3d31c26502122f349a21b592c8de" + integrity sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw== dependencies: tslib "^2.4.0" -"@tailwindcss/line-clamp@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@tailwindcss/line-clamp/-/line-clamp-0.4.0.tgz#03353e31e77636b785f2336e8c978502cec1de81" - integrity sha512-HQZo6gfx1D0+DU3nWlNLD5iA6Ef4JAXh0LeD8lOGrJwEDBwwJNKQza6WoXhhY1uQrxOuU8ROxV7CqiQV4CoiLw== +"@tailwindcss/line-clamp@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@tailwindcss/line-clamp/-/line-clamp-0.4.2.tgz#f353c5a8ab2c939c6267ac5b907f012e5ee130f9" + integrity sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw== -"@tailwindcss/typography@0.5.3": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.3.tgz#80c3419db470cc34b0d1442d05d82a1984bc66b7" - integrity sha512-Cn4MufL/xiTh2Npw26xiL7gP3GFkJH+zWM8DAm/NNEr4gF5N9D6gY9zMNNQUu27m8g0IIk665BUuoU92wVUBkA== +"@tailwindcss/typography@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.7.tgz#e0b95bea787ee14c5a34a74fc824e6fe86ea8855" + integrity sha512-JTTSTrgZfp6Ki4svhPA4mkd9nmQ/j9EfE7SbHJ1cLtthKkpW2OxsFXzSmxbhYbEkfNIyAyhle5p4SYyKRbz/jg== dependencies: lodash.castarray "^4.4.0" lodash.isplainobject "^4.0.6" lodash.merge "^4.6.2" + postcss-selector-parser "6.0.10" "@testing-library/dom@^8.5.0": - version "8.17.1" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.17.1.tgz#2d7af4ff6dad8d837630fecd08835aee08320ad7" - integrity sha512-KnH2MnJUzmFNPW6RIKfd+zf2Wue8mEKX0M3cpX6aKl5ZXrJM1/c/Pc8c2xDNYQCnJO48Sm5ITbMXgqTr3h4jxQ== + version "8.19.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.19.0.tgz#bd3f83c217ebac16694329e413d9ad5fdcfd785f" + integrity sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A== dependencies: "@babel/code-frame" "^7.10.4" "@babel/runtime" "^7.12.5" @@ -1889,9 +1893,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.18.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.1.tgz#ce5e2c8c272b99b7a9fd69fa39f0b4cd85028bd9" - integrity sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA== + version "7.18.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" + integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== dependencies: "@babel/types" "^7.3.0" @@ -2155,10 +2159,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*", "@types/jest@29.0.2": - version "29.0.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.0.2.tgz#05dcb2d78d2fcc444be89f95b7389f2c3601d336" - integrity sha512-TaklkwSEtvwJpleiKBHgEBySIQlcZ08gYP/s5wdtdLnjz9uxjnDd7U+Y0JWACebkqBc+jtbol2PEtEW0wQV2zQ== +"@types/jest@*", "@types/jest@29.2.2": + version "29.2.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.2.tgz#874e7dc6702fa6a3fe6107792aa98636dcc480b4" + integrity sha512-og1wAmdxKoS71K2ZwSVqWPX6OVn3ihZ6ZT2qvZvZQm90lJVDyXIjYcu4Khx2CNIeaFv12rOU/YObOsI3VOkzog== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -2177,10 +2181,10 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/jsonwebtoken@8.5.8": - version "8.5.8" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz#01b39711eb844777b7af1d1f2b4cf22fda1c0c44" - integrity sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A== +"@types/jsonwebtoken@8.5.9": + version "8.5.9" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz#2c064ecb0b3128d837d2764aa0b117b0ff6e4586" + integrity sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg== dependencies: "@types/node" "*" @@ -2191,20 +2195,15 @@ dependencies: "@types/unist" "*" -"@types/mdurl@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" - integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== - "@types/ms@*": version "0.7.31" resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*", "@types/node@18.7.18": - version "18.7.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.18.tgz#633184f55c322e4fb08612307c274ee6d5ed3154" - integrity sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg== +"@types/node@*", "@types/node@18.11.9": + version "18.11.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.9.tgz#02d013de7058cea16d36168ef2fc653464cfbad4" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== "@types/nprogress@0.2.0": version "0.2.0" @@ -2217,19 +2216,19 @@ integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/prettier@^2.1.5": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc" - integrity sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A== + version "2.7.1" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.1.tgz#dfd20e2dc35f027cdd6c1908e80a5ddc7499670e" + integrity sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow== "@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.5": version "15.7.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== -"@types/react-dom@18.0.6", "@types/react-dom@^18.0.0": - version "18.0.6" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.6.tgz#36652900024842b74607a17786b6662dd1e103a1" - integrity sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA== +"@types/react-dom@18.0.8", "@types/react-dom@^18.0.0": + version "18.0.8" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.8.tgz#d2606d855186cd42cc1b11e63a71c39525441685" + integrity sha512-C3GYO0HLaOkk9dDAz3Dl4sbe4AKUGTCfFIZsz3n/82dPNN8Du533HzKatDxeUYWu24wJgMP1xICqkWk1YOLOIw== dependencies: "@types/react" "*" @@ -2247,10 +2246,10 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@18.0.20": - version "18.0.20" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.20.tgz#e4c36be3a55eb5b456ecf501bd4a00fd4fd0c9ab" - integrity sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA== +"@types/react@*", "@types/react@18.0.25": + version "18.0.25" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.25.tgz#8b1dcd7e56fe7315535a4af25435e0bb55c8ae44" + integrity sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -2289,54 +2288,54 @@ integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^17.0.8": - version "17.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.12.tgz#0745ff3e4872b4ace98616d4b7e37ccbd75f9526" - integrity sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ== + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" + integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/parser@^5.21.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.37.0.tgz#c382077973f3a4ede7453fb14cadcad3970cbf3b" - integrity sha512-01VzI/ipYKuaG5PkE5+qyJ6m02fVALmMPY3Qq5BHflDx3y4VobbLdHQkSMg9VPRS4KdNt4oYTMaomFoHonBGAw== + version "5.42.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.42.0.tgz#be0ffbe279e1320e3d15e2ef0ad19262f59e9240" + integrity sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA== dependencies: - "@typescript-eslint/scope-manager" "5.37.0" - "@typescript-eslint/types" "5.37.0" - "@typescript-eslint/typescript-estree" "5.37.0" + "@typescript-eslint/scope-manager" "5.42.0" + "@typescript-eslint/types" "5.42.0" + "@typescript-eslint/typescript-estree" "5.42.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz#044980e4f1516a774a418dafe701a483a6c9f9ca" - integrity sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q== +"@typescript-eslint/scope-manager@5.42.0": + version "5.42.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.42.0.tgz#e1f2bb26d3b2a508421ee2e3ceea5396b192f5ef" + integrity sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow== dependencies: - "@typescript-eslint/types" "5.37.0" - "@typescript-eslint/visitor-keys" "5.37.0" + "@typescript-eslint/types" "5.42.0" + "@typescript-eslint/visitor-keys" "5.42.0" -"@typescript-eslint/types@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.37.0.tgz#09e4870a5f3af7af3f84e08d792644a87d232261" - integrity sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA== +"@typescript-eslint/types@5.42.0": + version "5.42.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.42.0.tgz#5aeff9b5eced48f27d5b8139339bf1ef805bad7a" + integrity sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw== -"@typescript-eslint/typescript-estree@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz#956dcf5c98363bcb97bdd5463a0a86072ff79355" - integrity sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA== +"@typescript-eslint/typescript-estree@5.42.0": + version "5.42.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.0.tgz#2592d24bb5f89bf54a63384ff3494870f95b3fd8" + integrity sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg== dependencies: - "@typescript-eslint/types" "5.37.0" - "@typescript-eslint/visitor-keys" "5.37.0" + "@typescript-eslint/types" "5.42.0" + "@typescript-eslint/visitor-keys" "5.42.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@5.37.0": - version "5.37.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz#7b72dd343295ea11e89b624995abc7103c554eee" - integrity sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA== +"@typescript-eslint/visitor-keys@5.42.0": + version "5.42.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.0.tgz#ee8d62d486f41cfe646632fab790fbf0c1db5bb0" + integrity sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg== dependencies: - "@typescript-eslint/types" "5.37.0" + "@typescript-eslint/types" "5.42.0" eslint-visitor-keys "^3.3.0" abab@^2.0.6: @@ -2344,13 +2343,13 @@ abab@^2.0.6: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== +acorn-globals@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" + integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" + acorn "^8.1.0" + acorn-walk "^8.0.2" acorn-jsx@^5.3.2: version "5.3.2" @@ -2366,20 +2365,25 @@ acorn-node@^1.8.2: acorn-walk "^7.0.0" xtend "^4.0.2" -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.0.0, acorn@^7.1.1: +acorn-walk@^8.0.2: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^7.0.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.7.1, acorn@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +acorn@^8.1.0, acorn@^8.8.0: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== agent-base@6: version "6.0.2" @@ -2472,9 +2476,11 @@ aria-query@^4.2.2: "@babel/runtime-corejs3" "^7.10.2" aria-query@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.2.tgz#0b8a744295271861e1d933f8feca13f9b70cfdc1" - integrity sha512-eigU3vhqSO+Z8BKDnVLN/ompjhf3pYzecKXz8+whRy+9gZu8n1TCGfwzQUUPnqdHl9ax1Hr9031orZ+UOEYr7Q== + version "5.1.3" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" array-includes@^3.1.4, array-includes@^3.1.5: version "3.1.5" @@ -2493,23 +2499,23 @@ array-union@^2.1.0: integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array.prototype.flat@^1.2.5: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" - integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" array.prototype.flatmap@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f" - integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg== + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" ast-types-flow@^0.0.7: @@ -2522,48 +2528,46 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -autoprefixer@10.4.7: - version "10.4.7" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.7.tgz#1db8d195f41a52ca5069b7593be167618edbbedf" - integrity sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA== +autoprefixer@10.4.13: + version "10.4.13" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" + integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg== dependencies: - browserslist "^4.20.3" - caniuse-lite "^1.0.30001335" + browserslist "^4.21.4" + caniuse-lite "^1.0.30001426" fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" postcss-value-parser "^4.2.0" +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + axe-core@^4.4.3: - version "4.4.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" - integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== + version "4.5.1" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.5.1.tgz#04d561c11b6d76d096d34e9d14ba2c294fb20cdc" + integrity sha512-1exVbW0X1O/HSr/WMwnaweyqcWOgZgLiVxdLG34pvSQk4NlYQr9OUy0JLwuhFfuVNQzzqgH57eYzkFBCb3bIsQ== axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== -babel-jest@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.0.3.tgz#64e156a47a77588db6a669a88dedff27ed6e260f" - integrity sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg== +babel-jest@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.2.2.tgz#2c15abd8c2081293c9c3f4f80a4ed1d51542fee5" + integrity sha512-kkq2QSDIuvpgfoac3WZ1OOcHsQQDU5xYk2Ql7tLdJ8BVAYbefEXal+NfS45Y5LVZA7cxC8KYcQMObpCt1J025w== dependencies: - "@jest/transform" "^29.0.3" + "@jest/transform" "^29.2.2" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.0.2" + babel-preset-jest "^29.2.0" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" @@ -2575,10 +2579,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^29.0.2: - version "29.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.0.2.tgz#ae61483a829a021b146c016c6ad39b8bcc37c2c8" - integrity sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg== +babel-plugin-jest-hoist@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094" + integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -2636,12 +2640,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^29.0.2: - version "29.0.2" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.0.2.tgz#e14a7124e22b161551818d89e5bdcfb3b2b0eac7" - integrity sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA== +babel-preset-jest@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc" + integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA== dependencies: - babel-plugin-jest-hoist "^29.0.2" + babel-plugin-jest-hoist "^29.2.0" babel-preset-current-node-syntax "^1.0.0" bail@^2.0.0: @@ -2693,12 +2697,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browserslist@^4.20.3, browserslist@^4.21.3: +browserslist@^4.21.3, browserslist@^4.21.4: version "4.21.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== @@ -2771,10 +2770,10 @@ can-use-dom@^0.1.0: resolved "https://registry.yarnpkg.com/can-use-dom/-/can-use-dom-0.1.0.tgz#22cc4a34a0abc43950f42c6411024a3f6366b45a" integrity sha512-ceOhN1DL7Y4O6M0j9ICgmTYziV89WMd96SvSl0REd8PMgrY0B/WBOPoed5S1KUmJqXgUXh8gzSe6E3ae27upsQ== -caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001335, caniuse-lite@^1.0.30001400: - version "1.0.30001400" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001400.tgz#3038bee70d8b875604cd8833cb0e5e254ee0281a" - integrity sha512-Mv659Hn65Z4LgZdJ7ge5JTVbE3rqbJaaXgW5LEI9/tOaXclfIZ8DW7D7FCWWWmWiiPS7AC48S8kf3DApSxQdgA== +caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001426: + version "1.0.30001430" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001430.tgz#638a8ae00b5a8a97e66ff43733b2701f81b101fa" + integrity sha512-IB1BXTZKPDVPM7cnV4iaKaHxckvdr/3xtctB3f7Hmenx3qYBhGtTZ//7EllK66aKXW98Lx0+7Yr0kxBtIt3tzg== ccount@^2.0.0: version "2.0.1" @@ -2837,9 +2836,9 @@ chownr@^1.1.1: integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== ci-info@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.4.0.tgz#b28484fd436cbc267900364f096c9dc185efb251" - integrity sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug== + version "3.5.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f" + integrity sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw== cjs-module-lexer@^1.0.0: version "1.2.2" @@ -2851,13 +2850,18 @@ classlist-polyfill@^1.0.3: resolved "https://registry.yarnpkg.com/classlist-polyfill/-/classlist-polyfill-1.2.0.tgz#935bc2dfd9458a876b279617514638bcaa964a2e" integrity sha512-GzIjNdcEtH4ieA2S8NmrSxv7DfEV5fmixQeyTmqmRmRJPGpRBaSnA2a0VrCjyT8iW8JjEdMbKzDotAJf+ajgaQ== -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== +client-only@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" wrap-ansi "^7.0.0" clsx@^1.2.1: @@ -2938,11 +2942,9 @@ concat-map@0.0.1: integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== cookie@0.5.0: version "0.5.0" @@ -2950,16 +2952,16 @@ cookie@0.5.0: integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== core-js-compat@^3.25.1: - version "3.25.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.1.tgz#6f13a90de52f89bbe6267e5620a412c7f7ff7e42" - integrity sha512-pOHS7O0i8Qt4zlPW/eIFjwp+NrTPx+wTL0ctgI2fHn31sZOq89rDsmtc/A2vAX7r6shl+bmVI+678He46jgBlw== + version "3.26.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.26.0.tgz#94e2cf8ba3e63800c4956ea298a6473bc9d62b44" + integrity sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A== dependencies: - browserslist "^4.21.3" + browserslist "^4.21.4" core-js-pure@^3.25.1: - version "3.25.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.1.tgz#79546518ae87cc362c991d9c2d211f45107991ee" - integrity sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A== + version "3.26.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.26.0.tgz#7ad8a5dd7d910756f3124374b50026e23265ca9a" + integrity sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA== core-js@^3.0.1: version "3.25.3" @@ -3049,7 +3051,7 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -csstype@^3.0.2, csstype@^3.1.0: +csstype@^3.0.2, csstype@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== @@ -3333,10 +3335,10 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -decimal.js@^10.3.1: - version "10.4.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.0.tgz#97a7448873b01e92e5ff9117d89a7bca8e63e0fe" - integrity sha512-Nv6ENEzyPQ6AItkGwLE2PGKinZZ9g59vSh2BeH6NqPu0OTKZ5ruJsVqh/orbAnqXc9pBbgXAIrc2EyaCj8NpGg== +decimal.js@^10.4.1: + version "10.4.2" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e" + integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA== decode-named-character-reference@^1.0.0: version "1.0.2" @@ -3357,6 +3359,27 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== +deep-equal@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.1.0.tgz#5ba60402cf44ab92c2c07f3f3312c3d857a0e1dd" + integrity sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA== + dependencies: + call-bind "^1.0.2" + es-get-iterator "^1.1.2" + get-intrinsic "^1.1.3" + is-arguments "^1.1.1" + is-date-object "^1.0.5" + is-regex "^1.1.4" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.8" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -3381,9 +3404,9 @@ define-properties@^1.1.3, define-properties@^1.1.4: object-keys "^1.1.1" defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" + integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== delaunator@5: version "5.0.0" @@ -3426,10 +3449,10 @@ didyoumean@^1.2.2: resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== -diff-sequences@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.0.0.tgz#bae49972ef3933556bcb0800b72e8579d19d9e4f" - integrity sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA== +diff-sequences@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.2.0.tgz#4c55b5b40706c7b5d2c5c75999a50c56d214e8f6" + integrity sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw== diff@^5.0.0: version "5.1.0" @@ -3527,14 +3550,14 @@ ecdsa-sig-formatter@1.0.11: safe-buffer "^5.0.1" electron-to-chromium@^1.4.251: - version "1.4.251" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.251.tgz#8b62448f3c591f0d32488df09454dda72dec96d5" - integrity sha512-k4o4cFrWPv4SoJGGAydd07GmlRVzmeDIJ6MaEChTUjk4Dmomn189tCicSzil2oyvbPoGgg2suwPDNWq4gWRhoQ== + version "1.4.284" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== -emittery@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" - integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^8.0.0: version "8.0.0" @@ -3558,7 +3581,7 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^4.3.0, entities@^4.4.0: +entities@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== @@ -3570,22 +3593,22 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: - version "1.20.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3" - integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ== +es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5, es-abstract@^1.20.4: + version "1.20.4" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861" + integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.1.2" + get-intrinsic "^1.1.3" get-symbol-description "^1.0.0" has "^1.0.3" has-property-descriptors "^1.0.0" has-symbols "^1.0.3" internal-slot "^1.0.3" - is-callable "^1.2.4" + is-callable "^1.2.7" is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" @@ -3595,10 +3618,25 @@ es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19 object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" string.prototype.trimend "^1.0.5" string.prototype.trimstart "^1.0.5" unbox-primitive "^1.0.2" +es-get-iterator@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.0" + has-symbols "^1.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.5" + isarray "^2.0.5" + es-shim-unscopables@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" @@ -3652,19 +3690,19 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-next@12.2.2: - version "12.2.2" - resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-12.2.2.tgz#4bb996026e118071849bc4011283a160ad5bde46" - integrity sha512-oJhWBLC4wDYYUFv/5APbjHUFd0QRFCojMdj/QnMoOEktmeTvwnnoA8F8uaXs0fQgsaTK0tbUxBRv9/Y4/rpxOA== +eslint-config-next@^13.0.0: + version "13.0.2" + resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-13.0.2.tgz#7c87837821ea7468e018ca41f3bf6fa37d53db68" + integrity sha512-SrrHp+zBDYLjOFZdM5b9aW/pliK687Xxfa+qpDuL08Z04ReHhmz3L+maXaAqgrEVZHQximP7nh0El4yNDJW+CA== dependencies: - "@next/eslint-plugin-next" "12.2.2" + "@next/eslint-plugin-next" "13.0.2" "@rushstack/eslint-patch" "^1.1.3" "@typescript-eslint/parser" "^5.21.0" eslint-import-resolver-node "^0.3.6" eslint-import-resolver-typescript "^2.7.1" eslint-plugin-import "^2.26.0" eslint-plugin-jsx-a11y "^6.5.1" - eslint-plugin-react "^7.29.4" + eslint-plugin-react "^7.31.7" eslint-plugin-react-hooks "^4.5.0" eslint-import-resolver-node@^0.3.6: @@ -3736,10 +3774,10 @@ eslint-plugin-react-hooks@^4.5.0: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== -eslint-plugin-react@^7.29.4: - version "7.31.8" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.8.tgz#3a4f80c10be1bcbc8197be9e8b641b2a3ef219bf" - integrity sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw== +eslint-plugin-react@^7.31.7: + version "7.31.10" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz#6782c2c7fe91c09e715d536067644bbb9491419a" + integrity sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA== dependencies: array-includes "^3.1.5" array.prototype.flatmap "^1.3.0" @@ -3781,13 +3819,15 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@8.19.0: - version "8.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.19.0.tgz#7342a3cbc4fbc5c106a1eefe0fd0b50b6b1a7d28" - integrity sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw== +eslint@8.26.0: + version "8.26.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.26.0.tgz#2bcc8836e6c424c4ac26a5674a70d44d84f2181d" + integrity sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg== dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" + "@eslint/eslintrc" "^1.3.3" + "@humanwhocodes/config-array" "^0.11.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -3797,18 +3837,21 @@ eslint@8.19.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.2" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" globals "^13.15.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -3820,9 +3863,8 @@ eslint@8.19.0: strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.3.2, espree@^9.4.0: +espree@^9.4.0: version "9.4.0" resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== @@ -3885,16 +3927,16 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -expect@^29.0.0, expect@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.0.3.tgz#6be65ddb945202f143c4e07c083f4f39f3bd326f" - integrity sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q== +expect@^29.0.0, expect@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.2.2.tgz#ba2dd0d7e818727710324a6e7f13dd0e6d086106" + integrity sha512-hE09QerxZ5wXiOhqkXy5d2G9ar+EqOyifnCXCpMNu+vZ6DG9TJ6CO2c2kPDSLqERTTWrO7OZj8EkYHQqSd78Yw== dependencies: - "@jest/expect-utils" "^29.0.3" - jest-get-type "^29.0.0" - jest-matcher-utils "^29.0.3" - jest-message-util "^29.0.3" - jest-util "^29.0.3" + "@jest/expect-utils" "^29.2.2" + jest-get-type "^29.2.0" + jest-matcher-utils "^29.2.2" + jest-message-util "^29.2.1" + jest-util "^29.2.1" extend@^3.0.0: version "3.0.2" @@ -3906,7 +3948,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11, fast-glob@^3.2.9: +fast-glob@^3.2.12, fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -3935,9 +3977,9 @@ fastq@^1.6.0: reusify "^1.0.4" fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" @@ -3968,6 +4010,14 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -3981,6 +4031,13 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -4025,11 +4082,6 @@ function.prototype.name@^1.1.5: es-abstract "^1.19.0" functions-have-names "^1.2.2" -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - functions-have-names@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" @@ -4045,7 +4097,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== @@ -4084,7 +4136,7 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1, glob-parent@^6.0.2: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -4139,11 +4191,23 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -4166,7 +4230,7 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" -has-symbols@^1.0.2, has-symbols@^1.0.3: +has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== @@ -4322,6 +4386,14 @@ internal-slot@^1.0.3: resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== +is-arguments@^1.1.0, is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -4359,19 +4431,19 @@ is-buffer@^2.0.0: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.6" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.6.tgz#fd6170b0b8c7e2cc73de342ef8284a2202023c44" - integrity sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q== +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== dependencies: has "^1.0.3" -is-date-object@^1.0.1: +is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== @@ -4400,6 +4472,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -4417,6 +4494,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" @@ -4435,6 +4517,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -4461,6 +4548,22 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" +is-typed-array@^1.1.10: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -4468,11 +4571,24 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -4489,9 +4605,9 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" - integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -4525,296 +4641,297 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.0.0.tgz#aa238eae42d9372a413dd9a8dadc91ca1806dce0" - integrity sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ== +jest-changed-files@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289" + integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA== dependencies: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.0.3.tgz#90faebc90295291cfc636b27dbd82e3bfb9e7a48" - integrity sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg== +jest-circus@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.2.2.tgz#1dc4d35fd49bf5e64d3cc505fb2db396237a6dfa" + integrity sha512-upSdWxx+Mh4DV7oueuZndJ1NVdgtTsqM4YgywHEx05UMH5nxxA2Qu9T9T9XVuR021XxqSoaKvSmmpAbjwwwxMw== dependencies: - "@jest/environment" "^29.0.3" - "@jest/expect" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/environment" "^29.2.2" + "@jest/expect" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/types" "^29.2.1" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^29.0.3" - jest-matcher-utils "^29.0.3" - jest-message-util "^29.0.3" - jest-runtime "^29.0.3" - jest-snapshot "^29.0.3" - jest-util "^29.0.3" + jest-each "^29.2.1" + jest-matcher-utils "^29.2.2" + jest-message-util "^29.2.1" + jest-runtime "^29.2.2" + jest-snapshot "^29.2.2" + jest-util "^29.2.1" p-limit "^3.1.0" - pretty-format "^29.0.3" + pretty-format "^29.2.1" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.0.3.tgz#fd8f0ef363a7a3d9c53ef62e0651f18eeffa77b9" - integrity sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ== +jest-cli@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.2.2.tgz#feaf0aa57d327e80d4f2f18d5f8cd2e77cac5371" + integrity sha512-R45ygnnb2CQOfd8rTPFR+/fls0d+1zXS6JPYTBBrnLPrhr58SSuPTiA5Tplv8/PXpz4zXR/AYNxmwIj6J6nrvg== dependencies: - "@jest/core" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/core" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/types" "^29.2.1" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.0.3" - jest-util "^29.0.3" - jest-validate "^29.0.3" + jest-config "^29.2.2" + jest-util "^29.2.1" + jest-validate "^29.2.2" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.0.3.tgz#c2e52a8f5adbd18de79f99532d8332a19e232f13" - integrity sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew== +jest-config@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.2.2.tgz#bf98623a46454d644630c1f0de8bba3f495c2d59" + integrity sha512-Q0JX54a5g1lP63keRfKR8EuC7n7wwny2HoTRDb8cx78IwQOiaYUVZAdjViY3WcTxpR02rPUpvNVmZ1fkIlZPcw== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.0.3" - "@jest/types" "^29.0.3" - babel-jest "^29.0.3" + "@jest/test-sequencer" "^29.2.2" + "@jest/types" "^29.2.1" + babel-jest "^29.2.2" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.0.3" - jest-environment-node "^29.0.3" - jest-get-type "^29.0.0" - jest-regex-util "^29.0.0" - jest-resolve "^29.0.3" - jest-runner "^29.0.3" - jest-util "^29.0.3" - jest-validate "^29.0.3" + jest-circus "^29.2.2" + jest-environment-node "^29.2.2" + jest-get-type "^29.2.0" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.2" + jest-runner "^29.2.2" + jest-util "^29.2.1" + jest-validate "^29.2.2" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.0.3" + pretty-format "^29.2.1" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.0.3.tgz#41cc02409ad1458ae1bf7684129a3da2856341ac" - integrity sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg== +jest-diff@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.2.1.tgz#027e42f5a18b693fb2e88f81b0ccab533c08faee" + integrity sha512-gfh/SMNlQmP3MOUgdzxPOd4XETDJifADpT937fN1iUGz+9DgOu2eUPHH25JDkLVcLwwqxv3GzVyK4VBUr9fjfA== dependencies: chalk "^4.0.0" - diff-sequences "^29.0.0" - jest-get-type "^29.0.0" - pretty-format "^29.0.3" + diff-sequences "^29.2.0" + jest-get-type "^29.2.0" + pretty-format "^29.2.1" -jest-docblock@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.0.0.tgz#3151bcc45ed7f5a8af4884dcc049aee699b4ceae" - integrity sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw== +jest-docblock@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" + integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== dependencies: detect-newline "^3.0.0" -jest-each@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.0.3.tgz#7ef3157580b15a609d7ef663dd4fc9b07f4e1299" - integrity sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg== +jest-each@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.2.1.tgz#6b0a88ee85c2ba27b571a6010c2e0c674f5c9b29" + integrity sha512-sGP86H/CpWHMyK3qGIGFCgP6mt+o5tu9qG4+tobl0LNdgny0aitLXs9/EBacLy3Bwqy+v4uXClqJgASJWcruYw== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" chalk "^4.0.0" - jest-get-type "^29.0.0" - jest-util "^29.0.3" - pretty-format "^29.0.3" - -jest-environment-jsdom@29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.0.3.tgz#0c6ee841133dd6acbe957bceaceea93b7ec60ca9" - integrity sha512-KIGvpm12c71hoYTjL4wC2c8K6KfhOHJqJtaHc1IApu5rG047YWZoEP13BlbucWfzGISBrmli8KFqdhdQEa8Wnw== - dependencies: - "@jest/environment" "^29.0.3" - "@jest/fake-timers" "^29.0.3" - "@jest/types" "^29.0.3" + jest-get-type "^29.2.0" + jest-util "^29.2.1" + pretty-format "^29.2.1" + +jest-environment-jsdom@29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.2.2.tgz#1e2d9f1f017fbaa7362a83e670b569158b4b8527" + integrity sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A== + dependencies: + "@jest/environment" "^29.2.2" + "@jest/fake-timers" "^29.2.2" + "@jest/types" "^29.2.1" "@types/jsdom" "^20.0.0" "@types/node" "*" - jest-mock "^29.0.3" - jest-util "^29.0.3" + jest-mock "^29.2.2" + jest-util "^29.2.1" jsdom "^20.0.0" -jest-environment-node@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.0.3.tgz#293804b1e0fa5f0e354dacbe510655caa478a3b2" - integrity sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg== +jest-environment-node@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.2.2.tgz#a64b272773870c3a947cd338c25fd34938390bc2" + integrity sha512-B7qDxQjkIakQf+YyrqV5dICNs7tlCO55WJ4OMSXsqz1lpI/0PmeuXdx2F7eU8rnPbRkUR/fItSSUh0jvE2y/tw== dependencies: - "@jest/environment" "^29.0.3" - "@jest/fake-timers" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/environment" "^29.2.2" + "@jest/fake-timers" "^29.2.2" + "@jest/types" "^29.2.1" "@types/node" "*" - jest-mock "^29.0.3" - jest-util "^29.0.3" + jest-mock "^29.2.2" + jest-util "^29.2.1" -jest-get-type@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.0.0.tgz#843f6c50a1b778f7325df1129a0fd7aa713aef80" - integrity sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw== +jest-get-type@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" + integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== -jest-haste-map@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.0.3.tgz#d7f3f7180f558d760eacc5184aac5a67f20ef939" - integrity sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A== +jest-haste-map@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.2.1.tgz#f803fec57f8075e6c55fb5cd551f99a72471c699" + integrity sha512-wF460rAFmYc6ARcCFNw4MbGYQjYkvjovb9GBT+W10Um8q5nHq98jD6fHZMDMO3tA56S8XnmNkM8GcA8diSZfnA== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^29.0.0" - jest-util "^29.0.3" - jest-worker "^29.0.3" + jest-regex-util "^29.2.0" + jest-util "^29.2.1" + jest-worker "^29.2.1" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.0.3.tgz#e85cf3391106a7a250850b6766b508bfe9c7bc6f" - integrity sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ== +jest-leak-detector@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.2.1.tgz#ec551686b7d512ec875616c2c3534298b1ffe2fc" + integrity sha512-1YvSqYoiurxKOJtySc+CGVmw/e1v4yNY27BjWTVzp0aTduQeA7pdieLiW05wTYG/twlKOp2xS/pWuikQEmklug== dependencies: - jest-get-type "^29.0.0" - pretty-format "^29.0.3" + jest-get-type "^29.2.0" + pretty-format "^29.2.1" -jest-matcher-utils@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.0.3.tgz#b8305fd3f9e27cdbc210b21fc7dbba92d4e54560" - integrity sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w== +jest-matcher-utils@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.2.2.tgz#9202f8e8d3a54733266784ce7763e9a08688269c" + integrity sha512-4DkJ1sDPT+UX2MR7Y3od6KtvRi9Im1ZGLGgdLFLm4lPexbTaCgJW5NN3IOXlQHF7NSHY/VHhflQ+WoKtD/vyCw== dependencies: chalk "^4.0.0" - jest-diff "^29.0.3" - jest-get-type "^29.0.0" - pretty-format "^29.0.3" + jest-diff "^29.2.1" + jest-get-type "^29.2.0" + pretty-format "^29.2.1" -jest-message-util@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.0.3.tgz#f0254e1ffad21890c78355726202cc91d0a40ea8" - integrity sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg== +jest-message-util@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.2.1.tgz#3a51357fbbe0cc34236f17a90d772746cf8d9193" + integrity sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.0.3" + pretty-format "^29.2.1" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.0.3.tgz#4f0093f6a9cb2ffdb9c44a07a3912f0c098c8de9" - integrity sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww== +jest-mock@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.2.2.tgz#9045618b3f9d27074bbcf2d55bdca6a5e2e8bca7" + integrity sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" "@types/node" "*" + jest-util "^29.2.1" jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.0.0.tgz#b442987f688289df8eb6c16fa8df488b4cd007de" - integrity sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug== +jest-regex-util@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" + integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== -jest-resolve-dependencies@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.0.3.tgz#f23a54295efc6374b86b198cf8efed5606d6b762" - integrity sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw== +jest-resolve-dependencies@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.2.tgz#1f444766f37a25f1490b5137408b6ff746a05d64" + integrity sha512-wWOmgbkbIC2NmFsq8Lb+3EkHuW5oZfctffTGvwsA4JcJ1IRk8b2tg+hz44f0lngvRTeHvp3Kyix9ACgudHH9aQ== dependencies: - jest-regex-util "^29.0.0" - jest-snapshot "^29.0.3" + jest-regex-util "^29.2.0" + jest-snapshot "^29.2.2" -jest-resolve@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.0.3.tgz#329a3431e3b9eb6629a2cd483e9bed95b26827b9" - integrity sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg== +jest-resolve@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.2.2.tgz#ad6436053b0638b41e12bbddde2b66e1397b35b5" + integrity sha512-3gaLpiC3kr14rJR3w7vWh0CBX2QAhfpfiQTwrFPvVrcHe5VUBtIXaR004aWE/X9B2CFrITOQAp5gxLONGrk6GA== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" + jest-haste-map "^29.2.1" jest-pnp-resolver "^1.2.2" - jest-util "^29.0.3" - jest-validate "^29.0.3" + jest-util "^29.2.1" + jest-validate "^29.2.2" resolve "^1.20.0" resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.0.3.tgz#2e47fe1e8777aea9b8970f37e8f83630b508fb87" - integrity sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw== +jest-runner@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.2.2.tgz#6b5302ed15eba8bf05e6b14d40f1e8d469564da3" + integrity sha512-1CpUxXDrbsfy9Hr9/1zCUUhT813kGGK//58HeIw/t8fa/DmkecEwZSWlb1N/xDKXg3uCFHQp1GCvlSClfImMxg== dependencies: - "@jest/console" "^29.0.3" - "@jest/environment" "^29.0.3" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/console" "^29.2.1" + "@jest/environment" "^29.2.2" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" "@types/node" "*" chalk "^4.0.0" - emittery "^0.10.2" + emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^29.0.0" - jest-environment-node "^29.0.3" - jest-haste-map "^29.0.3" - jest-leak-detector "^29.0.3" - jest-message-util "^29.0.3" - jest-resolve "^29.0.3" - jest-runtime "^29.0.3" - jest-util "^29.0.3" - jest-watcher "^29.0.3" - jest-worker "^29.0.3" + jest-docblock "^29.2.0" + jest-environment-node "^29.2.2" + jest-haste-map "^29.2.1" + jest-leak-detector "^29.2.1" + jest-message-util "^29.2.1" + jest-resolve "^29.2.2" + jest-runtime "^29.2.2" + jest-util "^29.2.1" + jest-watcher "^29.2.2" + jest-worker "^29.2.1" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.0.3.tgz#5a823ec5902257519556a4e5a71a868e8fd788aa" - integrity sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ== - dependencies: - "@jest/environment" "^29.0.3" - "@jest/fake-timers" "^29.0.3" - "@jest/globals" "^29.0.3" - "@jest/source-map" "^29.0.0" - "@jest/test-result" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" +jest-runtime@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.2.2.tgz#4068ee82423769a481460efd21d45a8efaa5c179" + integrity sha512-TpR1V6zRdLynckKDIQaY41od4o0xWL+KOPUCZvJK2bu5P1UXhjobt5nJ2ICNeIxgyj9NGkO0aWgDqYPVhDNKjA== + dependencies: + "@jest/environment" "^29.2.2" + "@jest/fake-timers" "^29.2.2" + "@jest/globals" "^29.2.2" + "@jest/source-map" "^29.2.0" + "@jest/test-result" "^29.2.1" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.0.3" - jest-message-util "^29.0.3" - jest-mock "^29.0.3" - jest-regex-util "^29.0.0" - jest-resolve "^29.0.3" - jest-snapshot "^29.0.3" - jest-util "^29.0.3" + jest-haste-map "^29.2.1" + jest-message-util "^29.2.1" + jest-mock "^29.2.2" + jest-regex-util "^29.2.0" + jest-resolve "^29.2.2" + jest-snapshot "^29.2.2" + jest-util "^29.2.1" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.0.3.tgz#0a024706986a915a6eefae74d7343069d2fc8eef" - integrity sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew== +jest-snapshot@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.2.2.tgz#1016ce60297b77382386bad561107174604690c2" + integrity sha512-GfKJrpZ5SMqhli3NJ+mOspDqtZfJBryGA8RIBxF+G+WbDoC7HCqKaeAss4Z/Sab6bAW11ffasx8/vGsj83jyjA== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" @@ -4822,81 +4939,87 @@ jest-snapshot@^29.0.3: "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.0.3" - "@jest/transform" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/expect-utils" "^29.2.2" + "@jest/transform" "^29.2.2" + "@jest/types" "^29.2.1" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.0.3" + expect "^29.2.2" graceful-fs "^4.2.9" - jest-diff "^29.0.3" - jest-get-type "^29.0.0" - jest-haste-map "^29.0.3" - jest-matcher-utils "^29.0.3" - jest-message-util "^29.0.3" - jest-util "^29.0.3" + jest-diff "^29.2.1" + jest-get-type "^29.2.0" + jest-haste-map "^29.2.1" + jest-matcher-utils "^29.2.2" + jest-message-util "^29.2.1" + jest-util "^29.2.1" natural-compare "^1.4.0" - pretty-format "^29.0.3" + pretty-format "^29.2.1" semver "^7.3.5" -jest-util@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.0.3.tgz#06d1d77f9a1bea380f121897d78695902959fbc0" - integrity sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ== +jest-util@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.2.1.tgz#f26872ba0dc8cbefaba32c34f98935f6cf5fc747" + integrity sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.0.3.tgz#f9521581d7344685428afa0a4d110e9c519aeeb6" - integrity sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw== +jest-validate@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.2.2.tgz#e43ce1931292dfc052562a11bc681af3805eadce" + integrity sha512-eJXATaKaSnOuxNfs8CLHgdABFgUrd0TtWS8QckiJ4L/QVDF4KVbZFBBOwCBZHOS0Rc5fOxqngXeGXE3nGQkpQA== dependencies: - "@jest/types" "^29.0.3" + "@jest/types" "^29.2.1" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.0.0" + jest-get-type "^29.2.0" leven "^3.1.0" - pretty-format "^29.0.3" + pretty-format "^29.2.1" -jest-watcher@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.0.3.tgz#8e220d1cc4f8029875e82015d084cab20f33d57f" - integrity sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw== +jest-watcher@^29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.2.2.tgz#7093d4ea8177e0a0da87681a9e7b09a258b9daf7" + integrity sha512-j2otfqh7mOvMgN2WlJ0n7gIx9XCMWntheYGlBK7+5g3b1Su13/UAK7pdKGyd4kDlrLwtH2QPvRv5oNIxWvsJ1w== dependencies: - "@jest/test-result" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/test-result" "^29.2.1" + "@jest/types" "^29.2.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - emittery "^0.10.2" - jest-util "^29.0.3" + emittery "^0.13.1" + jest-util "^29.2.1" string-length "^4.0.1" -jest-worker@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.0.3.tgz#c2ba0aa7e41eec9eb0be8e8a322ae6518df72647" - integrity sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng== +jest-worker@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.2.1.tgz#8ba68255438252e1674f990f0180c54dfa26a3b1" + integrity sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg== dependencies: "@types/node" "*" + jest-util "^29.2.1" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.0.3.tgz#5227a0596d30791b2649eea347e4aa97f734944d" - integrity sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ== +jest@29.2.2: + version "29.2.2" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.2.2.tgz#24da83cbbce514718acd698926b7679109630476" + integrity sha512-r+0zCN9kUqoON6IjDdjbrsWobXM/09Nd45kIPRD8kloaRh1z5ZCMdVsgLXGxmlL7UpAJsvCYOQNO+NjvG/gqiQ== dependencies: - "@jest/core" "^29.0.3" - "@jest/types" "^29.0.3" + "@jest/core" "^29.2.2" + "@jest/types" "^29.2.1" import-local "^3.0.2" - jest-cli "^29.0.3" + jest-cli "^29.2.2" + +js-sdsl@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" + integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -4919,17 +5042,17 @@ js-yaml@^4.1.0: argparse "^2.0.1" jsdom@^20.0.0: - version "20.0.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.0.tgz#882825ac9cc5e5bbee704ba16143e1fa78361ebf" - integrity sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA== + version "20.0.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.2.tgz#65ccbed81d5e877c433f353c58bb91ff374127db" + integrity sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA== dependencies: abab "^2.0.6" - acorn "^8.7.1" - acorn-globals "^6.0.0" + acorn "^8.8.0" + acorn-globals "^7.0.0" cssom "^0.5.0" cssstyle "^2.3.0" data-urls "^3.0.2" - decimal.js "^10.3.1" + decimal.js "^10.4.1" domexception "^4.0.0" escodegen "^2.0.0" form-data "^4.0.0" @@ -4937,18 +5060,17 @@ jsdom@^20.0.0: http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.1" is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "^7.0.0" + nwsapi "^2.2.2" + parse5 "^7.1.1" saxes "^6.0.0" symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" + tough-cookie "^4.1.2" w3c-xmlserializer "^3.0.0" webidl-conversions "^7.0.0" whatwg-encoding "^2.0.0" whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" - ws "^8.8.0" + ws "^8.9.0" xml-name-validator "^4.0.0" jsesc@^2.5.1: @@ -5072,7 +5194,7 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lilconfig@^2.0.5: +lilconfig@^2.0.5, lilconfig@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== @@ -5089,6 +5211,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.castarray@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" @@ -5253,9 +5382,9 @@ mdast-util-gfm-footnote@^1.0.0: micromark-util-normalize-identifier "^1.0.0" mdast-util-gfm-strikethrough@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.1.tgz#a4a74c36864ec6a6e3bbd31e1977f29beb475789" - integrity sha512-zKJbEPe+JP6EUv0mZ0tQUyLQOC+FADt0bARldONot/nefuISkaZFlmVK4tU6JgfyZGrky02m/I6PmehgAgZgqg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.2.tgz#6b4fa4ae37d449ccb988192ac0afbb2710ffcefd" + integrity sha512-T/4DVHXcujH6jx1yqpcAYYwd+z5lAYMw4Ls6yhTfbMMtCt0PHY4gEfhW9+lKsLBtyhUGKRIzcUA2FATVqnvPDA== dependencies: "@types/mdast" "^3.0.0" mdast-util-to-markdown "^1.3.0" @@ -5292,16 +5421,14 @@ mdast-util-gfm@^2.0.0: mdast-util-to-markdown "^1.0.0" mdast-util-to-hast@^12.1.0: - version "12.2.2" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.2.2.tgz#2bd8cf985a67c90c181eadcfdd8d31b8798ed9a1" - integrity sha512-lVkUttV9wqmdXFtEBXKcepvU/zfwbhjbkM5rxrquLW55dS1DfOrnAXCk5mg1be1sfY/WfMmayGy1NsbK1GLCYQ== + version "12.2.4" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.2.4.tgz#34c1ef2b6cf01c27b3e3504e2c977c76f722e7e1" + integrity sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg== dependencies: "@types/hast" "^2.0.0" "@types/mdast" "^3.0.0" - "@types/mdurl" "^1.0.0" mdast-util-definitions "^5.0.0" - mdurl "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" + micromark-util-sanitize-uri "^1.1.0" trim-lines "^3.0.0" unist-builder "^3.0.0" unist-util-generated "^2.0.0" @@ -5331,11 +5458,6 @@ mdn-data@2.0.14: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== -mdurl@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -5569,10 +5691,10 @@ micromark-util-resolve-all@^1.0.0: dependencies: micromark-util-types "^1.0.0" -micromark-util-sanitize-uri@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz#27dc875397cd15102274c6c6da5585d34d4f12b2" - integrity sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg== +micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz#f12e07a85106b902645e0364feb07cf253a85aee" + integrity sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg== dependencies: micromark-util-character "^1.0.0" micromark-util-encode "^1.0.0" @@ -5599,9 +5721,9 @@ micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: integrity sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w== micromark@^3.0.0: - version "3.0.10" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.0.10.tgz#1eac156f0399d42736458a14b0ca2d86190b457c" - integrity sha512-ryTDy6UUunOXy2HPjelppgJ2sNfcPz1pLlMdA6Rz9jPzhLikWXv/irpWV/I2jd68Uhmny7hHxAlAhk4+vWggpg== + version "3.1.0" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.1.0.tgz#eeba0fe0ac1c9aaef675157b52c166f125e89f62" + integrity sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA== dependencies: "@types/debug" "^4.0.0" debug "^4.0.0" @@ -5621,7 +5743,7 @@ micromark@^3.0.0: micromark-util-types "^1.0.1" uvu "^0.5.0" -micromatch@^4.0.4: +micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -5656,7 +5778,7 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -5664,9 +5786,9 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: brace-expansion "^1.1.7" minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6, minimist@~1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + version "1.2.7" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" + integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" @@ -5701,7 +5823,7 @@ multipipe@^1.0.2: duplexer2 "^0.1.2" object-assign "^4.1.0" -nanoid@^3.1.30, nanoid@^3.3.4: +nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== @@ -5716,36 +5838,36 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -next@12.2.0: - version "12.2.0" - resolved "https://registry.yarnpkg.com/next/-/next-12.2.0.tgz#aef47cd96b602bc1307d1dcf9a1ee3e753845544" - integrity sha512-B4j7D3SHYopLYx6/Ark0fenwIar9tEaZZFAaxmKjgcMMexhVJzB3jt7X+6wcdXPPMeUD6r09weUtnDpjox/vIA== - dependencies: - "@next/env" "12.2.0" - "@swc/helpers" "0.4.2" - caniuse-lite "^1.0.30001332" - postcss "8.4.5" - styled-jsx "5.0.2" - use-sync-external-store "1.1.0" +next@13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/next/-/next-13.0.2.tgz#b8c8642c70f736ed91105645391d335fc51c8f62" + integrity sha512-uQ5z5e4D9mOe8+upy6bQdYYjo/kk1v3jMW87kTy2TgAyAsEO+CkwRnMgyZ4JoHEnhPZLHwh7dk0XymRNLe1gFw== + dependencies: + "@next/env" "13.0.2" + "@swc/helpers" "0.4.11" + caniuse-lite "^1.0.30001406" + postcss "8.4.14" + styled-jsx "5.1.0" + use-sync-external-store "1.2.0" optionalDependencies: - "@next/swc-android-arm-eabi" "12.2.0" - "@next/swc-android-arm64" "12.2.0" - "@next/swc-darwin-arm64" "12.2.0" - "@next/swc-darwin-x64" "12.2.0" - "@next/swc-freebsd-x64" "12.2.0" - "@next/swc-linux-arm-gnueabihf" "12.2.0" - "@next/swc-linux-arm64-gnu" "12.2.0" - "@next/swc-linux-arm64-musl" "12.2.0" - "@next/swc-linux-x64-gnu" "12.2.0" - "@next/swc-linux-x64-musl" "12.2.0" - "@next/swc-win32-arm64-msvc" "12.2.0" - "@next/swc-win32-ia32-msvc" "12.2.0" - "@next/swc-win32-x64-msvc" "12.2.0" + "@next/swc-android-arm-eabi" "13.0.2" + "@next/swc-android-arm64" "13.0.2" + "@next/swc-darwin-arm64" "13.0.2" + "@next/swc-darwin-x64" "13.0.2" + "@next/swc-freebsd-x64" "13.0.2" + "@next/swc-linux-arm-gnueabihf" "13.0.2" + "@next/swc-linux-arm64-gnu" "13.0.2" + "@next/swc-linux-arm64-musl" "13.0.2" + "@next/swc-linux-x64-gnu" "13.0.2" + "@next/swc-linux-x64-musl" "13.0.2" + "@next/swc-win32-arm64-msvc" "13.0.2" + "@next/swc-win32-ia32-msvc" "13.0.2" + "@next/swc-win32-x64-msvc" "13.0.2" node-abi@^3.3.0: - version "3.24.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.24.0.tgz#b9d03393a49f2c7e147d0c99f180e680c27c1599" - integrity sha512-YPG3Co0luSu6GwOBsmIdGW6Wx0NyNDLg/hriIyDllVsNwnI6UeqaWShxC3lbH4LtEQUgoLP3XR1ndXiDAWvmRw== + version "3.28.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.28.0.tgz#b0df8b317e1c4f2f323756c5fc8ffccc5bca4718" + integrity sha512-fRlDb4I0eLcQeUvGq7IY3xHrSb0c9ummdvDSYWfT9+LKP+3jCKw/tKoqaM7r1BAoiAC6GtwyjaGnOz6B3OtF+A== dependencies: semver "^7.3.5" @@ -5793,7 +5915,7 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -nwsapi@^2.2.0: +nwsapi@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== @@ -5813,6 +5935,14 @@ object-inspect@^1.12.2, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -5823,7 +5953,7 @@ object-keys@~0.4.0: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" integrity sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw== -object.assign@^4.1.0, object.assign@^4.1.3, object.assign@^4.1.4: +object.assign@^4.1.3, object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -5913,7 +6043,7 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-limit@^3.1.0: +p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -5927,6 +6057,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -5949,7 +6086,7 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse5@^7.0.0: +parse5@^7.0.0, parse5@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.1.tgz#4649f940ccfb95d8754f37f73078ea20afe0c746" integrity sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg== @@ -6024,22 +6161,22 @@ postcss-js@^4.0.0: dependencies: camelcase-css "^2.0.1" -postcss-load-config@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" - integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== +postcss-load-config@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" + integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== dependencies: lilconfig "^2.0.5" - yaml "^2.1.1" + yaml "^1.10.2" -postcss-nested@5.0.6: - version "5.0.6" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-5.0.6.tgz#466343f7fc8d3d46af3e7dba3fcd47d052a945bc" - integrity sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA== +postcss-nested@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.0.tgz#1572f1984736578f360cffc7eb7dca69e30d1735" + integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== dependencies: - postcss-selector-parser "^6.0.6" + postcss-selector-parser "^6.0.10" -postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.6: +postcss-selector-parser@6.0.10, postcss-selector-parser@^6.0.10: version "6.0.10" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== @@ -6061,19 +6198,10 @@ postcss@8.4.14: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@8.4.5: - version "8.4.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95" - integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg== - dependencies: - nanoid "^3.1.30" - picocolors "^1.0.0" - source-map-js "^1.0.1" - -postcss@^8.4.14: - version "8.4.16" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" - integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== +postcss@8.4.18, postcss@^8.4.18: + version "8.4.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.18.tgz#6d50046ea7d3d66a85e0e782074e7203bc7fbca2" + integrity sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA== dependencies: nanoid "^3.3.4" picocolors "^1.0.0" @@ -6116,10 +6244,10 @@ pretty-format@^27.0.2: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^29.0.0, pretty-format@^29.0.3: - version "29.0.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.0.3.tgz#23d5f8cabc9cbf209a77d49409d093d61166a811" - integrity sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q== +pretty-format@^29.0.0, pretty-format@^29.2.1: + version "29.2.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.2.1.tgz#86e7748fe8bbc96a6a4e04fa99172630907a9611" + integrity sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA== dependencies: "@jest/schemas" "^29.0.0" ansi-styles "^5.0.0" @@ -6203,10 +6331,10 @@ react-dom@18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" -react-hook-form@7.33.1: - version "7.33.1" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.33.1.tgz#8c4410e3420788d3b804d62cc4c142915c2e46d0" - integrity sha512-ydTfTxEJdvgjCZBj5DDXRc58oTEfnFupEwwTAQ9FSKzykEJkX+3CiAkGtAMiZG7IPWHuzgT6AOBfogiKhUvKgg== +react-hook-form@7.39.1: + version "7.39.1" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.39.1.tgz#ded87d4b3f6692d1f9219515f78ca282b6e1ebf7" + integrity sha512-MiF9PCILN5KulhSGbnjohMiTOrB47GerDTichMNP0y2cPUu1GTRFqbunOxCE9N1499YTLMV/ne4gFzqCp1rxrQ== react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" @@ -6327,10 +6455,10 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.13.10: + version "0.13.10" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" + integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== regenerator-transform@^0.15.0: version "0.15.0" @@ -6511,6 +6639,15 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -6540,23 +6677,23 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.5, semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== dependencies: lru-cache "^6.0.0" -sharp@0.31.0: - version "0.31.0" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.0.tgz#ce9b5202a5667486721cf07fd5b52360b1c2275a" - integrity sha512-ft96f8WzGxavg0rkLpMw90MTPMUZDyf0tHjPPh8Ob59xt6KzX8EqtotcqZGUm7kwqpX2pmYiyYX2LL0IZ/FDEw== +sharp@0.31.2: + version "0.31.2" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.31.2.tgz#a8411c80512027f5a452b76d599268760c4e5dfa" + integrity sha512-DUdNVEXgS5A97cTagSLIIp8dUZ/lZtk78iNVZgHdHbx1qnQR7JAHY0BnXnwwH39Iw+VKhO08CTYhIg0p98vQ5Q== dependencies: color "^4.2.3" detect-libc "^2.0.1" node-addon-api "^5.0.0" prebuild-install "^7.1.1" - semver "^7.3.7" + semver "^7.3.8" simple-get "^4.0.1" tar-fs "^2.1.1" tunnel-agent "^0.6.0" @@ -6638,7 +6775,7 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -source-map-js@^1.0.1, source-map-js@^1.0.2: +source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -6797,15 +6934,17 @@ style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -styled-jsx@5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.2.tgz#ff230fd593b737e9e68b630a694d460425478729" - integrity sha512-LqPQrbBh3egD57NBcHET4qcgshPks+yblyhPlH2GY8oaDgKs8SK4C3dBh3oSJjgzJ3G5t1SYEZGHkP+QEpX9EQ== +styled-jsx@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.0.tgz#4a5622ab9714bd3fcfaeec292aa555871f057563" + integrity sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ== + dependencies: + client-only "0.0.1" -stylis@4.0.13: - version "4.0.13" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" - integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== +stylis@4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7" + integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA== supports-color@^5.3.0: version "5.5.0" @@ -6814,7 +6953,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -6828,14 +6967,6 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" - integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -6864,10 +6995,10 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -tailwindcss@3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.1.5.tgz#c8e0bb1cbacf29a6411d9c07debc1af9d388d4ca" - integrity sha512-bC/2dy3dGPqxMWAqFSRgQxVCfmO/31ZbeEp8s9DMDh4zgPZ5WW1gxRJkbBkXcTUIzaSUdhWrcsrSOe32ccgB4w== +tailwindcss@3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.2.tgz#705f78cec8f4de2feb52abdb7a8a056e67f2d736" + integrity sha512-c2GtSdqg+harR4QeoTmex0Ngfg8IIHNeLQH5yr2B9uZbZR1Xt1rYbjWOWTcj3YLTZhrmZnPowoQDbSRFyZHQ5Q== dependencies: arg "^5.0.2" chokidar "^3.5.3" @@ -6875,18 +7006,19 @@ tailwindcss@3.1.5: detective "^5.2.1" didyoumean "^1.2.2" dlv "^1.1.3" - fast-glob "^3.2.11" + fast-glob "^3.2.12" glob-parent "^6.0.2" is-glob "^4.0.3" - lilconfig "^2.0.5" + lilconfig "^2.0.6" + micromatch "^4.0.5" normalize-path "^3.0.0" object-hash "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.14" + postcss "^8.4.18" postcss-import "^14.1.0" postcss-js "^4.0.0" - postcss-load-config "^4.0.1" - postcss-nested "5.0.6" + postcss-load-config "^3.1.4" + postcss-nested "6.0.0" postcss-selector-parser "^6.0.10" postcss-value-parser "^4.2.0" quick-lru "^5.1.1" @@ -6913,14 +7045,6 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -6965,7 +7089,7 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tough-cookie@^4.0.0: +tough-cookie@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== @@ -7008,9 +7132,9 @@ tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.0, tslib@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + version "2.4.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== tsutils@^3.21.0: version "3.21.0" @@ -7055,10 +7179,10 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typescript@4.8.3: - version "4.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" - integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== +typescript@4.8.4: + version "4.8.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" + integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== unbox-primitive@^1.0.2: version "1.0.2" @@ -7160,9 +7284,9 @@ universalify@^0.2.0: integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== update-browserslist-db@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" - integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -7182,10 +7306,10 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -use-sync-external-store@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.1.0.tgz#3343c3fe7f7e404db70f8c687adf5c1652d34e82" - integrity sha512-SEnieB2FPKEVne66NpXPd1Np4R1lTNKfjuy3XdIoPQKYBAFdzbzSZlSn1KJZUiihQLQC5Znot4SBz1EOTBwQAQ== +use-sync-external-store@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" @@ -7202,11 +7326,6 @@ uvu@^0.5.0: kleur "^4.0.3" sade "^1.7.3" -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - v8-to-istanbul@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" @@ -7234,13 +7353,6 @@ vfile@^5.0.0: unist-util-stringify-position "^3.0.0" vfile-message "^3.0.0" -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - w3c-xmlserializer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" @@ -7296,6 +7408,28 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.8: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -7330,10 +7464,10 @@ write-file-atomic@^4.0.1: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^8.8.0: - version "8.8.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" - integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== +ws@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.10.0.tgz#00a28c09dfb76eae4eb45c3b565f771d6951aa51" + integrity sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw== xml-name-validator@^4.0.0: version "4.0.0" @@ -7367,33 +7501,28 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0: +yaml@^1.10.0, yaml@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yaml@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec" - integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw== - -yargs-parser@^21.0.0: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.3.1: - version "17.5.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" - integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + version "17.6.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" + integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== dependencies: - cliui "^7.0.2" + cliui "^8.0.1" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^21.0.0" + yargs-parser "^21.1.1" yocto-queue@^0.1.0: version "0.1.0"