From 23b76fd490bfbba006d04aad2f71a98b41b2792e Mon Sep 17 00:00:00 2001 From: awildturtok <1553491+awildturtok@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:37:31 +0200 Subject: [PATCH 01/28] cleanup money (#3535) * restructures ResultType and decouples printing into ResultPrinters: - ResultType is now very simple mix of primitive enum and LIST. (We hope to remove even more logic from it) - Result printing was always weird with Mappings embedded in StringT. We've moved that responsibility into ResultInfo via SelectResultInfo for mapped Selects. - This PR opens the possibility to embed anonymization into the ResultInfo. - PrintSettings now caches the C10n calls as they were before that sometimes invoked per cell, which should make rendering faster. * Reworks Printers: - We inject the result specific Printers using the printerFactory. This untangles the burden of formatting. - Now a Select claiming to produce a specific type only needs to guarantee they are in a format capable of being handled by the printers it elects to use: This allows us later to make a printer that alters the result before printing it, without having to inject into all renderers. * reworks Money to no longer be "cent" based and instead just use it as storage primitive. Is now BigDecimal - pull default for decimalShift from CurrencyConfig --- .../com/bakdata/conquery/ResultHeaders.java | 97 ++-- .../conquery/apiv1/QueryProcessor.java | 13 +- .../apiv1/query/ArrayConceptQuery.java | 7 +- .../conquery/apiv1/query/CQElement.java | 3 +- .../bakdata/conquery/apiv1/query/CQYes.java | 3 +- .../conquery/apiv1/query/ConceptQuery.java | 7 +- .../bakdata/conquery/apiv1/query/Query.java | 3 +- .../apiv1/query/SecondaryIdQuery.java | 9 +- .../apiv1/query/TableExportQuery.java | 42 +- .../apiv1/query/concept/specific/CQAnd.java | 21 +- .../query/concept/specific/CQConcept.java | 7 +- .../concept/specific/CQDateRestriction.java | 5 +- .../query/concept/specific/CQNegation.java | 5 +- .../apiv1/query/concept/specific/CQOr.java | 21 +- .../query/concept/specific/CQReusedQuery.java | 5 +- .../concept/specific/external/CQExternal.java | 5 +- .../temporal/CQAbstractTemporalQuery.java | 7 +- .../io/result/arrow/ArrowRenderer.java | 469 +++++++++--------- .../conquery/io/result/arrow/ArrowUtil.java | 93 ++-- .../io/result/arrow/ResultArrowProcessor.java | 7 +- .../conquery/io/result/arrow/RowConsumer.java | 21 +- .../conquery/io/result/csv/CsvRenderer.java | 31 +- .../io/result/csv/ResultCsvProcessor.java | 2 +- .../io/result/excel/ExcelRenderer.java | 239 +++++---- .../io/result/excel/ResultExcelProcessor.java | 2 +- .../parquet/EntityResultWriteSupport.java | 235 +++++---- .../io/result/parquet/ParquetRenderer.java | 96 ++-- .../parquet/ResultParquetProcessor.java | 4 +- .../mode/cluster/InternalMapperFactory.java | 5 +- .../bakdata/conquery/models/common/Range.java | 197 ++++---- .../conquery/models/config/ExcelConfig.java | 18 +- .../models/config/ExcelResultProvider.java | 9 +- .../models/config/IdColumnConfig.java | 27 +- .../filters/specific/NumberFilter.java | 35 +- .../datasets/concepts/select/Select.java | 11 +- .../select/concept/ConceptColumnSelect.java | 18 +- .../select/connector/DistinctSelect.java | 10 +- .../select/connector/SingleColumnSelect.java | 7 +- .../specific/CountOccurencesSelect.java | 53 -- .../specific/MappableSingleColumnSelect.java | 18 +- .../conquery/models/events/Bucket.java | 2 +- .../conquery/models/events/EmptyBucket.java | 2 +- .../conquery/models/events/EmptyStore.java | 6 +- .../models/events/stores/root/MoneyStore.java | 6 +- .../events/stores/specific/MoneyIntStore.java | 65 ++- .../forms/managed/AbsoluteFormQuery.java | 13 +- .../models/forms/managed/EntityDateQuery.java | 11 +- .../forms/managed/ManagedInternalForm.java | 5 +- .../forms/managed/RelativeFormQuery.java | 15 +- .../preproc/parser/specific/MoneyParser.java | 41 +- .../conquery/models/query/ManagedQuery.java | 11 +- .../models/query/SingleTableResult.java | 16 +- .../filter/event/number/MoneyFilterNode.java | 4 +- .../query/preview/EntityPreviewExecution.java | 342 ++++++------- .../specific/MultiSelectAggregator.java | 80 --- .../specific/SelectAggregator.java | 60 --- .../diffsum/MoneyDiffSumAggregator.java | 15 +- .../specific/sum/MoneySumAggregator.java | 14 +- .../query/resultinfo/ColumnResultInfo.java | 30 +- .../query/resultinfo/ExternalResultInfo.java | 31 +- .../resultinfo/FixedLabelResultInfo.java | 33 +- .../models/query/resultinfo/ResultInfo.java | 33 +- .../resultinfo/SecondaryIdResultInfo.java | 54 ++ .../query/resultinfo/SelectResultInfo.java | 21 +- .../models/query/resultinfo/UniqueNamer.java | 4 +- .../printers/ArrowResultPrinters.java | 31 ++ .../printers/ExcelResultPrinters.java | 59 +++ .../printers/JavaResultPrinters.java | 76 +++ .../printers/JsonResultPrinters.java | 27 + .../query/resultinfo/printers/Printer.java | 15 + .../resultinfo/printers/PrinterFactory.java | 56 +++ .../resultinfo/printers/ResultPrinters.java | 231 --------- .../printers/SecondaryIdResultInfo.java | 44 -- .../printers/StringResultPrinters.java | 61 +++ .../printers/common/BooleanStringPrinter.java | 25 + .../printers/common/ConceptIdPrinter.java | 30 ++ .../printers/common/DatePrinter.java | 13 + .../common/DateRangeStringPrinter.java | 37 ++ .../printers/common/DateStringPrinter.java | 14 + .../printers/common/IdentityPrinter.java | 12 + .../printers/common/ListStringPrinter.java | 31 ++ .../printers/common/LocalizedEnumPrinter.java | 18 + .../printers/common/MappedPrinter.java | 13 + .../common/NumberFormatStringPrinter.java | 22 + .../printers/common/StringPrinter.java | 13 + .../printers/common/ToStringPrinter.java | 14 + .../BooleanColumnStatsCollector.java | 9 +- .../statistics/ColumnStatsCollector.java | 8 +- .../statistics/DateColumnStatsCollector.java | 5 +- .../HistogramColumnDescription.java | 2 +- .../NumberColumnStatsCollector.java | 9 +- .../query/statistics/ResultStatistics.java | 63 ++- .../StringColumnStatsCollector.java | 7 +- .../model/filter/NumberFilterConverter.java | 33 +- .../query/AbsoluteFormQueryConverter.java | 2 +- .../query/ConceptQueryConverter.java | 2 +- .../query/EntityDateQueryConverter.java | 2 +- .../query/RelativFormQueryConverter.java | 2 +- .../query/SecondaryIdQueryConverter.java | 2 +- .../query/TableExportQueryConverter.java | 2 +- .../api/StoredQueriesProcessorTest.java | 9 +- .../DefaultSqlCDateSetParserTest.java | 5 +- .../integration/common/IntegrationUtils.java | 9 +- .../json/AbstractQueryEngineTest.java | 6 +- .../conquery/integration/json/FormTest.java | 96 ++-- .../conquery/io/result/ResultTestUtil.java | 93 ++-- .../arrow/ArrowResultGenerationTest.java | 364 +++++++------- .../result/csv/CsvResultGenerationTest.java | 102 ++-- .../result/excel/ExcelResultRenderTest.java | 136 ++--- .../parquet/ParquetResultGenerationTest.java | 22 +- .../types/ColumnStoreSerializationTests.java | 6 +- .../models/query/DefaultColumnNameTest.java | 4 +- .../conquery/models/query/UniqueNameTest.java | 16 +- .../conquery/models/types/ResultTypeTest.java | 137 ++--- .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 69 --- .../MULTI_SELECT_AGGREGATOR/content.csv | 10 - .../MULTI_SELECT_AGGREGATOR/expected.csv | 7 - .../SIMPLE_VIRTUAL_CONCEPT_Query.test.json | 66 --- .../aggregator/SELECT_AGGREGATOR/content.csv | 6 - .../aggregator/SELECT_AGGREGATOR/expected.csv | 5 - .../number_money/real_range/content.csv | 19 - .../number_money/real_range/expected.csv | 6 - .../real_range/number_money.spec.json | 73 --- .../e2e/backend-admin-ui/test_2_dataset.cy.js | 2 +- .../support/test_data/all_types.concept.json | 6 - .../js/entity-history/timeline/EventCard.tsx | 2 +- .../timeline/GroupedContent.tsx | 2 +- 127 files changed, 2568 insertions(+), 2481 deletions(-) delete mode 100644 backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountOccurencesSelect.java delete mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/MultiSelectAggregator.java delete mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/SelectAggregator.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ArrowResultPrinters.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ExcelResultPrinters.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JavaResultPrinters.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JsonResultPrinters.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/Printer.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/PrinterFactory.java delete mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ResultPrinters.java delete mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/SecondaryIdResultInfo.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/StringResultPrinters.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/BooleanStringPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ConceptIdPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DatePrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateStringPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/IdentityPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/LocalizedEnumPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/MappedPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/NumberFormatStringPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/StringPrinter.java create mode 100644 backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ToStringPrinter.java delete mode 100644 backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json delete mode 100644 backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/content.csv delete mode 100644 backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/expected.csv delete mode 100644 backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json delete mode 100644 backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/content.csv delete mode 100644 backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/expected.csv delete mode 100644 backend/src/test/resources/tests/sql/filter/number_money/real_range/content.csv delete mode 100644 backend/src/test/resources/tests/sql/filter/number_money/real_range/expected.csv delete mode 100644 backend/src/test/resources/tests/sql/filter/number_money/real_range/number_money.spec.json diff --git a/backend/src/main/java/com/bakdata/conquery/ResultHeaders.java b/backend/src/main/java/com/bakdata/conquery/ResultHeaders.java index 9d3eb527e3..e42347476b 100644 --- a/backend/src/main/java/com/bakdata/conquery/ResultHeaders.java +++ b/backend/src/main/java/com/bakdata/conquery/ResultHeaders.java @@ -9,64 +9,105 @@ import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.FixedLabelResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.common.LocalizedEnumPrinter; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import lombok.experimental.UtilityClass; @UtilityClass public class ResultHeaders { - public static ResultInfo datesInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()).dates(); + public static ResultInfo datesInfo() { final ResultType.ListT type = new ResultType.ListT<>(ResultType.Primitive.DATE_RANGE); - return new FixedLabelResultInfo(label, label, type, Set.of(new SemanticType.EventDateT()), settings, ResultPrinters.printerFor(type, settings)); + return new FixedLabelResultInfo(type, Set.of(new SemanticType.EventDateT())){ + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).dates(); + } + }; } - public static ResultInfo historyDatesInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()).dates(); + public static ResultInfo historyDatesInfo() { final ResultType.ListT type = new ResultType.ListT<>(ResultType.Primitive.DATE_RANGE); - return new FixedLabelResultInfo(label, label, type, Set.of(new SemanticType.EventDateT(), new SemanticType.GroupT()), settings, ResultPrinters.printerFor(type, settings)); + return new FixedLabelResultInfo(type, Set.of(new SemanticType.EventDateT(), new SemanticType.GroupT())) { + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).dates(); + } + }; } - public static ResultInfo sourceInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()).source(); - - return new FixedLabelResultInfo(label, label, ResultType.Primitive.STRING, Set.of(new SemanticType.SourcesT(), new SemanticType.CategoricalT(), new SemanticType.GroupT()), settings, ResultPrinters.printerFor(ResultType.Primitive.STRING, settings)); + public static ResultInfo sourceInfo() { + return new FixedLabelResultInfo(ResultType.Primitive.STRING, Set.of(new SemanticType.SourcesT(), new SemanticType.CategoricalT(), new SemanticType.GroupT())) { + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).source(); + } + }; } - public static ResultInfo formContextInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()).index(); + public static ResultInfo formContextInfo() { - return new FixedLabelResultInfo(label, label, ResultType.Primitive.INTEGER, Set.of(), settings, ResultPrinters.printerFor(ResultType.Primitive.INTEGER, settings)); + return new FixedLabelResultInfo(ResultType.Primitive.INTEGER, Set.of()) { + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).index(); + } + }; } - public static ResultInfo formDateRangeInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()) - .dateRange(); + public static ResultInfo formDateRangeInfo() { - return new FixedLabelResultInfo(label, label, ResultType.Primitive.DATE_RANGE, Set.of(), settings, ResultPrinters.printerFor(ResultType.Primitive.DATE_RANGE, settings)); + return new FixedLabelResultInfo(ResultType.Primitive.DATE_RANGE, Set.of()) { + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).dateRange(); + } + }; } - public static ResultInfo formResolutionInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()).resolution(); + public static ResultInfo formResolutionInfo() { + + return new FixedLabelResultInfo(ResultType.Primitive.STRING, Set.of()) { + @Override + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + return new LocalizedEnumPrinter<>(printSettings, Resolution.class); + } - return new FixedLabelResultInfo(label, label, ResultType.Primitive.STRING, Set.of(), settings, new ResultPrinters.LocalizedEnumPrinter<>(settings, Resolution.class)); + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).resolution(); + } + }; } - public static ResultInfo formEventDateInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()) - .eventDate(); + public static ResultInfo formEventDateInfo() { - return new FixedLabelResultInfo(label, label, ResultType.Primitive.DATE, Set.of(), settings, ResultPrinters.printerFor(ResultType.Primitive.DATE, settings)); + return new FixedLabelResultInfo(ResultType.Primitive.DATE, Set.of()) { + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).eventDate(); + } + }; } - public static ResultInfo formObservationScopeInfo(PrintSettings settings) { - final String label = C10nCache.getLocalized(ResultHeadersC10n.class, settings.getLocale()).observationScope(); + public static ResultInfo formObservationScopeInfo() { + + return new FixedLabelResultInfo(ResultType.Primitive.STRING, Set.of()) { + @Override + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + return new LocalizedEnumPrinter<>(printSettings, FeatureGroup.class); + } - return new FixedLabelResultInfo(label, label, ResultType.Primitive.STRING, Set.of(), settings, new ResultPrinters.LocalizedEnumPrinter<>(settings, FeatureGroup.class)); + @Override + public String userColumnName(PrintSettings printSettings) { + return C10nCache.getLocalized(ResultHeadersC10n.class, printSettings.getLocale()).observationScope(); + } + }; } } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java b/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java index e2c8448df5..d3f28b692e 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java @@ -73,6 +73,7 @@ import com.bakdata.conquery.models.query.queryplan.DateAggregationAction; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; +import com.bakdata.conquery.models.query.resultinfo.printers.JavaResultPrinters; import com.bakdata.conquery.models.query.statistics.ResultStatistics; import com.bakdata.conquery.models.query.visitor.QueryVisitor; import com.bakdata.conquery.models.types.SemanticType; @@ -585,7 +586,7 @@ public ResultStatistics getResultStatistics(SingleTableResult managedQuery) { new PrintSettings(true, locale, managedQuery.getNamespace(), config, null, null, decimalFormat, integerFormat); final UniqueNamer uniqueNamer = new UniqueNamer(printSettings); - final List resultInfos = managedQuery.getResultInfos(printSettings); + final List resultInfos = managedQuery.getResultInfos(); final Optional dateInfo = @@ -593,7 +594,15 @@ public ResultStatistics getResultStatistics(SingleTableResult managedQuery) { final Optional dateIndex = dateInfo.map(resultInfos::indexOf); - return ResultStatistics.collectResultStatistics(managedQuery, resultInfos, dateInfo, dateIndex, printSettings, uniqueNamer, config); + return ResultStatistics.collectResultStatistics(managedQuery, + resultInfos, + dateInfo, + dateIndex, + printSettings, + uniqueNamer, + config, + new JavaResultPrinters() + ); } } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java index 32e7871b23..057b7ac86c 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ArrayConceptQuery.java @@ -11,7 +11,6 @@ import com.bakdata.conquery.io.jackson.View; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; import com.bakdata.conquery.models.query.Visitable; @@ -93,9 +92,9 @@ public void collectRequiredQueries(Set requiredQueries) { } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { final List resultInfos = new ArrayList<>(); - ResultInfo dateInfo = ResultHeaders.datesInfo(printSettings); + ResultInfo dateInfo = ResultHeaders.datesInfo(); if(getResolvedDateAggregationMode() != DateAggregationMode.NONE){ // Add one DateInfo for the whole Query @@ -103,7 +102,7 @@ public List getResultInfos(PrintSettings printSettings) { } int lastIndex = resultInfos.size(); - childQueries.forEach(q -> resultInfos.addAll(q.getResultInfos(printSettings))); + childQueries.forEach(q -> resultInfos.addAll(q.getResultInfos())); if(!resultInfos.isEmpty()) { // Remove DateInfo from each childQuery diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQElement.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQElement.java index cf309dcf90..61806adfb4 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQElement.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQElement.java @@ -11,7 +11,6 @@ import com.bakdata.conquery.io.cps.CPSBase; import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -79,7 +78,7 @@ public final Set collectRequiredQueries() { public abstract void collectRequiredQueries(Set requiredQueries) ; @JsonIgnore - public abstract List getResultInfos(PrintSettings settings); + public abstract List getResultInfos(); public void visit(Consumer visitor) { visitor.accept(this); diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQYes.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQYes.java index 2e3e34a727..8bdc6a00d6 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQYes.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/CQYes.java @@ -6,7 +6,6 @@ import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; import com.bakdata.conquery.models.query.queryplan.ConceptQueryPlan; @@ -33,7 +32,7 @@ public void collectRequiredQueries(Set requiredQueries) { } @Override - public List getResultInfos(PrintSettings settings) { + public List getResultInfos() { return Collections.emptyList(); } } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ConceptQuery.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ConceptQuery.java index 6f028f3684..0f3393f006 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/ConceptQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/ConceptQuery.java @@ -10,7 +10,6 @@ import com.bakdata.conquery.io.jackson.View; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -80,16 +79,16 @@ public void resolve(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { Preconditions.checkNotNull(resolvedDateAggregationMode); final List resultInfos = new ArrayList<>(); if (resolvedDateAggregationMode != DateAggregationMode.NONE) { - resultInfos.add(ResultHeaders.datesInfo(printSettings)); + resultInfos.add(ResultHeaders.datesInfo()); } - resultInfos.addAll(root.getResultInfos(printSettings)); + resultInfos.addAll(root.getResultInfos()); return resultInfos; } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/Query.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/Query.java index 59d80a904c..e81cd67dc9 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/Query.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/Query.java @@ -12,7 +12,6 @@ import com.bakdata.conquery.models.execution.ManagedExecution; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.ManagedQuery; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; import com.bakdata.conquery.models.query.queryplan.QueryPlan; @@ -39,7 +38,7 @@ public Set collectRequiredQueries() { } @JsonIgnore - public abstract List getResultInfos(PrintSettings printSettings); + public abstract List getResultInfos(); @Override public ManagedQuery toManagedExecution(User user, Dataset submittedDataset, MetaStorage storage, DatasetRegistry datasetRegistry) { diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/SecondaryIdQuery.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/SecondaryIdQuery.java index 85ba3ddc9a..acced1a092 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/SecondaryIdQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/SecondaryIdQuery.java @@ -18,7 +18,6 @@ import com.bakdata.conquery.models.error.ConqueryError; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -27,7 +26,7 @@ import com.bakdata.conquery.models.query.queryplan.ConceptQueryPlan; import com.bakdata.conquery.models.query.queryplan.SecondaryIdQueryPlan; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.SecondaryIdResultInfo; +import com.bakdata.conquery.models.query.resultinfo.SecondaryIdResultInfo; import com.fasterxml.jackson.annotation.JsonView; import jakarta.validation.constraints.NotNull; import lombok.Getter; @@ -125,12 +124,12 @@ public void resolve(final QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { final List resultInfos = new ArrayList<>(); - resultInfos.add(new SecondaryIdResultInfo(secondaryId, printSettings)); + resultInfos.add(new SecondaryIdResultInfo(secondaryId)); - resultInfos.addAll(query.getResultInfos(printSettings)); + resultInfos.addAll(query.getResultInfos()); return resultInfos; } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/TableExportQuery.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/TableExportQuery.java index c8f88d8dbb..18176a428d 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/TableExportQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/TableExportQuery.java @@ -5,7 +5,6 @@ import java.util.Collection; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -31,7 +30,6 @@ import com.bakdata.conquery.models.datasets.concepts.ValidityDate; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -41,8 +39,7 @@ import com.bakdata.conquery.models.query.queryplan.TableExportQueryPlan; import com.bakdata.conquery.models.query.resultinfo.ColumnResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; -import com.bakdata.conquery.models.query.resultinfo.printers.SecondaryIdResultInfo; +import com.bakdata.conquery.models.query.resultinfo.SecondaryIdResultInfo; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import com.fasterxml.jackson.annotation.JsonCreator; @@ -168,8 +165,8 @@ public void resolve(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings printSettings) { - return createResultInfos(conceptColumns, printSettings); + public List getResultInfos() { + return createResultInfos(conceptColumns); } private Map calculateSecondaryIdPositions(AtomicInteger currentPosition) { @@ -222,21 +219,21 @@ private static Map calculateColumnPositions(AtomicInteger curre return positions; } - private List createResultInfos(Set conceptColumns, PrintSettings printSettings) { + private List createResultInfos(Set conceptColumns) { final int size = positions.values().stream().mapToInt(i -> i).max().getAsInt() + 1; final ResultInfo[] infos = new ResultInfo[size]; - infos[0] = ResultHeaders.historyDatesInfo(printSettings); - infos[1] = ResultHeaders.sourceInfo(printSettings); + infos[0] = ResultHeaders.historyDatesInfo(); + infos[1] = ResultHeaders.sourceInfo(); for (Map.Entry e : secondaryIdPositions.entrySet()) { final SecondaryIdDescription desc = e.getKey(); final Integer pos = e.getValue(); - infos[pos] = new SecondaryIdResultInfo(desc, printSettings); + infos[pos] = new SecondaryIdResultInfo(desc); } @@ -263,30 +260,27 @@ private List createResultInfos(Set conceptColumns, PrintSett continue; } - final Set semantics = new HashSet<>(); - - ResultType resultType = ResultType.resolveResultType(column.getType()); - ResultPrinters.Printer printer = ResultPrinters.printerFor(resultType, printSettings); - + final ResultInfo columnResultInfo; if (connectorColumns.containsKey(column)) { - // Additionally, Concept Columns are returned as ConceptElementId, when rawConceptColumns is not set. - final Concept concept = connectorColumns.get(column).getConcept(); + // Additionally, Concept Columns are returned as ConceptElementId, when rawConceptColumns is not set. + columnResultInfo = new ColumnResultInfo(column, ResultType.Primitive.STRING, column.getDescription(), isRawConceptValues() ? null : concept); + // Columns that are used to build concepts are marked as ConceptColumn. - semantics.add(new SemanticType.ConceptColumnT(concept)); + columnResultInfo.addSemantics(new SemanticType.ConceptColumnT(concept)); - if (!isRawConceptValues()) { - resultType = ResultType.Primitive.STRING; - printer = new ResultPrinters.ConceptIdPrinter(concept, printSettings); - } + infos[position] = columnResultInfo; } else { // If it's not a connector column, we just link to the source column. - semantics.add(new SemanticType.ColumnT(column)); + columnResultInfo = new ColumnResultInfo(column, ResultType.resolveResultType(column.getType()), column.getDescription(), null); + columnResultInfo.addSemantics(new SemanticType.ColumnT(column)); } - infos[position] = new ColumnResultInfo(column, resultType, semantics, printer, column.getDescription(), printSettings); + infos[position] = columnResultInfo; + + } return List.of(infos); diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java index f49ff668f9..bce7cdd346 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQAnd.java @@ -28,7 +28,6 @@ import com.bakdata.conquery.models.query.queryplan.specific.AndNode; import com.bakdata.conquery.models.query.resultinfo.FixedLabelResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.util.QueryUtils; import com.fasterxml.jackson.annotation.JsonView; @@ -113,18 +112,24 @@ private DateAggregationAction determineDateAction(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings settings) { + public List getResultInfos() { final List resultInfos = new ArrayList<>(); for (CQElement c : children) { - resultInfos.addAll(c.getResultInfos(settings)); + resultInfos.addAll(c.getResultInfos()); } if (createExists()) { - final ResultPrinters.BooleanPrinter printer = new ResultPrinters.BooleanPrinter(settings); - final String userOrDefaultLabel = getUserOrDefaultLabel(settings.getLocale()); - final String defaultLabel = defaultLabel(settings.getLocale()); - - resultInfos.add(new FixedLabelResultInfo(userOrDefaultLabel, defaultLabel, ResultType.Primitive.BOOLEAN, Set.of(), settings, printer)); + resultInfos.add(new FixedLabelResultInfo(ResultType.Primitive.BOOLEAN, Set.of()) { + @Override + public String userColumnName(PrintSettings printSettings) { + return getUserOrDefaultLabel(printSettings.getLocale()); + } + + @Override + public String defaultColumnName(PrintSettings printSettings) { + return defaultLabel(printSettings.getLocale()); + } + }); } return resultInfos; } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQConcept.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQConcept.java index 538a987d93..be0e5814e9 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQConcept.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQConcept.java @@ -24,7 +24,6 @@ import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; import com.bakdata.conquery.models.query.NamespacedIdentifiableHolding; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -286,16 +285,16 @@ private ValidityDate selectValidityDate(CQTable table) { } @Override - public List getResultInfos(PrintSettings settings) { + public List getResultInfos() { final List resultInfos = new ArrayList<>(); for (Select select : selects) { - resultInfos.add(select.getResultInfo(this, settings)); + resultInfos.add(select.getResultInfo(this)); } for (CQTable table : tables) { for (Select sel : table.getSelects()) { - resultInfos.add(sel.getResultInfo(this, settings)); + resultInfos.add(sel.getResultInfo(this)); } } diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQDateRestriction.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQDateRestriction.java index 251f5c779b..6f78e0be8f 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQDateRestriction.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQDateRestriction.java @@ -12,7 +12,6 @@ import com.bakdata.conquery.models.common.Range; import com.bakdata.conquery.models.common.daterange.CDateRange; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -60,8 +59,8 @@ public void resolve(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings settings) { - return child.getResultInfos(settings); + public List getResultInfos() { + return child.getResultInfos(); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java index 2ae44af793..57fbef50f4 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQNegation.java @@ -8,7 +8,6 @@ import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.io.jackson.View; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; import com.bakdata.conquery.models.query.Visitable; @@ -67,8 +66,8 @@ private DateAggregationAction determineDateAction(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings settings) { - return child.getResultInfos(settings); + public List getResultInfos() { + return child.getResultInfos(); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java index 6037200bea..882ead8a2b 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQOr.java @@ -28,7 +28,6 @@ import com.bakdata.conquery.models.query.queryplan.specific.OrNode; import com.bakdata.conquery.models.query.resultinfo.FixedLabelResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.util.QueryUtils; import com.fasterxml.jackson.annotation.JsonView; @@ -118,18 +117,24 @@ private DateAggregationAction determineDateAction(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings settings) { + public List getResultInfos() { List resultInfos = new ArrayList<>(); for (CQElement c : children) { - resultInfos.addAll(c.getResultInfos(settings)); + resultInfos.addAll(c.getResultInfos()); } if (createExists()) { - final ResultPrinters.BooleanPrinter printer = new ResultPrinters.BooleanPrinter(settings); - final String userOrDefaultLabel = getUserOrDefaultLabel(settings.getLocale()); - final String defaultLabel = defaultLabel(settings.getLocale()); - - resultInfos.add(new FixedLabelResultInfo(userOrDefaultLabel, defaultLabel, ResultType.Primitive.BOOLEAN, Set.of(), settings, printer)); + resultInfos.add(new FixedLabelResultInfo(ResultType.Primitive.BOOLEAN, Set.of()) { + @Override + public String userColumnName(PrintSettings printSettings) { + return getUserOrDefaultLabel(printSettings.getLocale()); + } + + @Override + public String defaultColumnName(PrintSettings printSettings) { + return defaultLabel(printSettings.getLocale()); + } + }); } return resultInfos; diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQReusedQuery.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQReusedQuery.java index 7162f8f4fb..496fa51120 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQReusedQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/CQReusedQuery.java @@ -13,7 +13,6 @@ import com.bakdata.conquery.models.error.ConqueryError; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.ManagedQuery; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -93,8 +92,8 @@ public void visit(Consumer visitor) { } @Override - public List getResultInfos(PrintSettings settings) { - return resolvedQuery.getReusableComponents().getResultInfos(settings); + public List getResultInfos() { + return resolvedQuery.getReusableComponents().getResultInfos(); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/external/CQExternal.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/external/CQExternal.java index d6d23de78d..7815d7fe03 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/external/CQExternal.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/external/CQExternal.java @@ -19,7 +19,6 @@ import com.bakdata.conquery.models.config.IdColumnConfig; import com.bakdata.conquery.models.error.ConqueryError; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -215,7 +214,7 @@ public RequiredEntities collectRequiredEntities(QueryExecutionContext context) { } @Override - public List getResultInfos(PrintSettings settings) { + public List getResultInfos() { if (extra == null) { return Collections.emptyList(); } @@ -228,7 +227,7 @@ public List getResultInfos(PrintSettings settings) { final String column = headers[col]; final ResultType type = onlySingles ? ResultType.Primitive.STRING : new ResultType.ListT<>(ResultType.Primitive.STRING); - resultInfos.add(new ExternalResultInfo(column, type, settings)); + resultInfos.add(new ExternalResultInfo(column, type)); } return resultInfos; diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/temporal/CQAbstractTemporalQuery.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/temporal/CQAbstractTemporalQuery.java index 33a720c5ea..63e33a0616 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/temporal/CQAbstractTemporalQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/specific/temporal/CQAbstractTemporalQuery.java @@ -8,7 +8,6 @@ import com.bakdata.conquery.apiv1.query.CQElement; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -81,10 +80,10 @@ public void resolve(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings settings) { + public List getResultInfos() { List resultInfos = new ArrayList<>(); - resultInfos.addAll(index.getChild().getResultInfos(settings)); - resultInfos.addAll(preceding.getChild().getResultInfos(settings)); + resultInfos.addAll(index.getChild().getResultInfos()); + resultInfos.addAll(preceding.getChild().getResultInfos()); return resultInfos; } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowRenderer.java b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowRenderer.java index fde3a9ad80..d1f84adf31 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowRenderer.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowRenderer.java @@ -9,19 +9,21 @@ import java.util.stream.Stream; import com.bakdata.conquery.models.common.CDate; +import com.bakdata.conquery.models.common.daterange.CDateRange; import com.bakdata.conquery.models.config.ArrowConfig; import com.bakdata.conquery.models.identifiable.mapping.PrintIdMapper; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.query.results.EntityResult; +import com.bakdata.conquery.models.types.ResultType; import lombok.extern.slf4j.Slf4j; import org.apache.arrow.util.Preconditions; import org.apache.arrow.vector.BitVector; import org.apache.arrow.vector.DateDayVector; import org.apache.arrow.vector.FieldVector; -import org.apache.arrow.vector.Float4Vector; import org.apache.arrow.vector.Float8Vector; import org.apache.arrow.vector.IntVector; import org.apache.arrow.vector.ValueVector; @@ -33,277 +35,288 @@ import org.apache.arrow.vector.types.pojo.Field; import org.apache.arrow.vector.types.pojo.Schema; import org.apache.arrow.vector.util.Text; +import org.jetbrains.annotations.NotNull; @Slf4j public class ArrowRenderer { - public static void renderToStream( + public static void renderToStream( Function writerProducer, PrintSettings printSettings, ArrowConfig arrowConfig, List idHeaders, List resultInfo, - Stream results) throws IOException { + Stream results, PrinterFactory printerFactory) throws IOException { - List fields = ArrowUtil.generateFields(idHeaders, resultInfo, new UniqueNamer(printSettings)); - VectorSchemaRoot root = VectorSchemaRoot.create(new Schema(fields, null), ROOT_ALLOCATOR); + final List fields = ArrowUtil.generateFields(idHeaders, resultInfo, new UniqueNamer(printSettings), printSettings); + final VectorSchemaRoot root = VectorSchemaRoot.create(new Schema(fields, null), ROOT_ALLOCATOR); // Build separate pipelines for id and value, as they have different sources but the same target - RowConsumer[] idWriters = generateWriterPipeline(root, 0, idHeaders.size(), printSettings, idHeaders); - RowConsumer[] valueWriter = generateWriterPipeline(root, idHeaders.size(), resultInfo.size(), printSettings, resultInfo); + final RowConsumer[] idWriters = generateWriterPipeline(root, 0, idHeaders.size(), idHeaders); + final RowConsumer[] valueWriter = generateWriterPipeline(root, idHeaders.size(), resultInfo.size(), resultInfo); + + final List printers = + Stream.concat(idHeaders.stream(), resultInfo.stream()) + .map(info -> info.createPrinter(printerFactory, printSettings)) + .toList(); // Write the data try (ArrowWriter writer = writerProducer.apply(root)) { - write(writer, root, idWriters, valueWriter, printSettings.getIdMapper(), results, arrowConfig.getBatchSize()); + write(writer, root, idWriters, valueWriter, printSettings.getIdMapper(), printers, results, arrowConfig.getBatchSize()); } - } + } public static void write( ArrowWriter writer, VectorSchemaRoot root, - RowConsumer[] idWriter, - RowConsumer[] valueWriter, + RowConsumer[] idWriters, + RowConsumer[] valueWriters, PrintIdMapper idMapper, + List printers, Stream results, int batchSize) throws IOException { Preconditions.checkArgument(batchSize > 0, "Batch size needs be larger than 0."); // TODO add time metric for writing - log.trace("Starting result write"); - writer.start(); - int batchCount = 0; - int batchLineCount = 0; - Iterator resultIterator = results.iterator(); - while (resultIterator.hasNext()) { - EntityResult cer = resultIterator.next(); - for (Object[] line : cer.listResultLines()) { - if(line.length != valueWriter.length) { - throw new IllegalStateException("The number of value writers and values in a result line differs. Writers: " + valueWriter.length + " Line: " + line.length); - } - for (RowConsumer rowConsumer : idWriter) { - // Write id information - rowConsumer.accept(batchLineCount, idMapper.map(cer).getExternalId()); - } - for (RowConsumer rowConsumer : valueWriter) { - // Write values - rowConsumer.accept(batchLineCount, line); - } - batchLineCount++; - - if (batchLineCount >= batchSize) { - root.setRowCount(batchLineCount); - writer.writeBatch(); - root.clear(); - batchLineCount = 0; - } - } - } - if (batchLineCount > 0) { - root.setRowCount(batchLineCount); - writer.writeBatch(); - root.clear(); - batchCount++; - } - log.trace("Wrote {} batches of size {} (last batch might be smaller)", batchCount, batchSize); - writer.end(); - } - - private static RowConsumer intVectorFiller(IntVector vector, Function resultExtractor) { - return (rowNumber, line) -> { - Integer value = resultExtractor.apply(line); - if (value == null) { - vector.setNull(rowNumber); - return; - } - vector.setSafe(rowNumber, value); - }; - } - - private static RowConsumer bitVectorFiller(BitVector vector, Function resultExtractor) { - return (rowNumber, line) -> { - Boolean value = resultExtractor.apply(line); - if (value == null) { - vector.setNull(rowNumber); - return; - } - vector.setSafe(rowNumber, value ? 1 : 0); - }; - } - - private static RowConsumer float8VectorFiller(Float8Vector vector, Function resultExtractor) { - return (rowNumber, line) -> { - Number value = resultExtractor.apply(line); - if (value == null) { - vector.setNull(rowNumber); - return; - } - vector.setSafe(rowNumber, value.doubleValue()); - }; - } - - private static RowConsumer float4VectorFiller(Float4Vector vector, Function resultExtractor) { - return (rowNumber, line) -> { - Number value = resultExtractor.apply(line); - if (value == null) { - vector.setNull(rowNumber); - return; - } - vector.setSafe(rowNumber, value.floatValue()); - }; - } - - private static RowConsumer varCharVectorFiller(VarCharVector vector, Function resultExtractor) { - return (rowNumber, line) -> { - String value = resultExtractor.apply(line); - if (value == null) { - vector.setNull(rowNumber); - return; - } - vector.setSafe(rowNumber, new Text(value)); - }; - } - - private static RowConsumer dateDayVectorFiller(DateDayVector vector, Function resultExtractor) { - return (rowNumber, line) -> { - Number value = resultExtractor.apply(line); - if (value == null) { - vector.setNull(rowNumber); - return; - } - - // Treat our internal infinity dates (Interger.MIN and Integer.MAX) also as null - final int epochDay = value.intValue(); - if (CDate.isNegativeInfinity(epochDay) || CDate.isPositiveInfinity(epochDay)) { - vector.setNull(rowNumber); - return; - } - - vector.setSafe(rowNumber, epochDay); - }; - } - - private static RowConsumer structVectorFiller(StructVector vector, RowConsumer [] nestedConsumers, Function> resultExtractor) { - return (rowNumber, line) -> { - // Values is a horizontal list - List values = resultExtractor.apply(line); - if (values == null) { - vector.setNull(rowNumber); - return; - } - if(values.size() != nestedConsumers.length) { - throw new IllegalStateException("The number of the provided nested value differs from the number of consumer for the generated vectors. Provided values: " + values + "\t Available consumers: " + nestedConsumers.length); - } - for (RowConsumer nestedConsumer : nestedConsumers) { - nestedConsumer.accept(rowNumber, values.toArray()); - } - - // Finally mark that we populated the nested vectors - vector.setIndexDefined(rowNumber); - }; - } - - private static RowConsumer listVectorFiller(ListVector vector, RowConsumer nestedConsumer, Function> resultExtractor){ - return (rowNumber, line) -> { - // Values is a vertical list - List values = resultExtractor.apply(line); - if (values == null) { - vector.setNull(rowNumber); - return; - } - - int start = vector.startNewValue(rowNumber); - - for (int i = 0; i < values.size(); i++) { - // These short lived one value arrays are a workaround at the moment - nestedConsumer.accept(Math.addExact(start, i), new Object[] {values.get(i)}); - } - - vector.endValue(rowNumber, values.size()); - }; - } - - - public static RowConsumer[] generateWriterPipeline(VectorSchemaRoot root, int vectorOffset, int numVectors, final PrintSettings settings, List resultInfos) { - Preconditions.checkArgument(vectorOffset >= 0, "Offset was negative: %s", vectorOffset); - Preconditions.checkArgument(numVectors >= 0, "Number of vectors was negative: %s", numVectors); - - RowConsumer[] builder = new RowConsumer[numVectors]; - - for ( - int vecI = vectorOffset; - (vecI < root.getFieldVectors().size()) && (vecI < vectorOffset + numVectors); - vecI++ - ) { - final int pos = vecI - vectorOffset; - final FieldVector vector = root.getVector(vecI); - final ResultInfo resultInfo = resultInfos.get(pos); - builder[pos] = generateVectorFiller(pos, vector, settings, resultInfo.getPrinter()); + log.trace("Starting result write"); + + writer.start(); + int batchCount = 0; + int batchLineCount = 0; + final Iterator resultIterator = results.iterator(); + + while (resultIterator.hasNext()) { + final EntityResult cer = resultIterator.next(); + + final Object[] printedExternalId = getPrintedExternalId(idWriters, idMapper, printers, cer); + + for (Object[] line : cer.listResultLines()) { + Preconditions.checkState( + line.length == valueWriters.length, + "The number of value writers and values in a result line differs. Writers: %d Line: %d".formatted(valueWriters.length, line.length) + ); + + for (int index = 0; index < idWriters.length; index++) { + if (printedExternalId[index] == null) { + continue; + } + + idWriters[index].accept(batchLineCount, printedExternalId[index]); + } + + for (int index = 0; index < valueWriters.length; index++) { + final int colId = index + idWriters.length; + // In this case, the printer normalizes and adjusts values. + + final Object value = line[index]; + + Object printed = null; + + if (value != null) { + Printer printer = printers.get(colId); + printed = printer.apply(value); + } + + valueWriters[index].accept(batchLineCount, printed); + } + batchLineCount++; + + if (batchLineCount >= batchSize) { + root.setRowCount(batchLineCount); + writer.writeBatch(); + root.clear(); + batchLineCount = 0; + } + } + } + if (batchLineCount > 0) { + root.setRowCount(batchLineCount); + writer.writeBatch(); + root.clear(); + batchCount++; } - return builder; + log.trace("Wrote {} batches of size {} (last batch might be smaller)", batchCount, batchSize); + writer.end(); + } - } + @NotNull + private static Object[] getPrintedExternalId(RowConsumer[] idWriters, PrintIdMapper idMapper, List printers, EntityResult cer) { + final String[] externalId = idMapper.map(cer).getExternalId(); - private static RowConsumer generateVectorFiller(int pos, ValueVector vector, final PrintSettings settings, ResultPrinters.Printer printer) { - if (vector instanceof IntVector intVector) { - return intVectorFiller(intVector, (line) -> (Integer) line[pos]); + final Object[] printedExternalId = new String[externalId.length]; + + for (int index = 0; index < idWriters.length; index++) { + Printer printer = printers.get(index); + printedExternalId[index] = printer.apply(externalId[index]); } + return printedExternalId; + } + + private static RowConsumer intVectorFiller(IntVector vector) { + return (rowNumber, valueRaw) -> { + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + + final Integer value = (Integer) valueRaw; + + vector.setSafe(rowNumber, value); + }; + } + + private static RowConsumer bitVectorFiller(BitVector vector) { + return (rowNumber, valueRaw) -> { + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + + final Boolean value = (Boolean) valueRaw; + + vector.setSafe(rowNumber, value ? 1 : 0); + }; + } + + private static RowConsumer moneyVectorFiller(IntVector vector) { + return (rowNumber, valueRaw) -> { + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + + final int value = (int) valueRaw; + + vector.setSafe(rowNumber, value); + }; + } + + private static RowConsumer float8VectorFiller(Float8Vector vector) { + return (rowNumber, valueRaw) -> { + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + + final Number value = (Number) valueRaw; + + vector.setSafe(rowNumber, value.doubleValue()); + }; + } + + private static RowConsumer varCharVectorFiller(VarCharVector vector) { + return (rowNumber, valueRaw) -> { + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + final String value = (String) valueRaw; + vector.setSafe(rowNumber, new Text(value)); + }; + } + + private static RowConsumer dateDayVectorFiller(DateDayVector vector) { + return (rowNumber, valueRaw) -> { + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + + final Number value = (Number) valueRaw; + + // Treat our internal infinity dates (Interger.MIN and Integer.MAX) also as null + final int epochDay = value.intValue(); + + if (CDate.isNegativeInfinity(epochDay) || CDate.isPositiveInfinity(epochDay)) { + vector.setNull(rowNumber); + return; + } + + vector.setSafe(rowNumber, epochDay); + }; + } + + private static RowConsumer dateRangeVectorFiller(StructVector vector) { + final List nestedVectors = vector.getPrimitiveVectors(); + final RowConsumer minConsumer = generateVectorFiller(nestedVectors.get(0), ResultType.Primitive.DATE); + final RowConsumer maxConsumer = generateVectorFiller(nestedVectors.get(1), ResultType.Primitive.DATE); + + return ((rowNumber, valueRaw) -> { + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + + final CDateRange value = (CDateRange) valueRaw; + + minConsumer.accept(rowNumber, value.getMinValue()); + maxConsumer.accept(rowNumber, value.getMaxValue()); + + // Finally mark that we populated the nested vectors + vector.setIndexDefined(rowNumber); + }); + } + + private static RowConsumer listVectorFiller(ListVector vector, RowConsumer nestedConsumer) { + return (rowNumber, valueRaw) -> { + + if (valueRaw == null) { + vector.setNull(rowNumber); + return; + } + + final List values = (List) valueRaw; - if (vector instanceof VarCharVector varCharVector) { - return varCharVectorFiller( - varCharVector, - (line) -> { - // This is a bit clunky at the moment, since this lambda is executed for each textual value - // in the result, but it should be okay for now. This code moves as soon shards deliver themselves - // arrow as a result. + final int start = vector.startNewValue(rowNumber); - if (line[pos] == null) { - // If there is no value, we don't want to have it displayed as an empty string (see next if) - return null; - } - // We reference the printer directly, - return printer.print(line[pos]); - }); - } + for (int i = 0; i < values.size(); i++) { + nestedConsumer.accept(Math.addExact(start, i), values.get(i)); + } - if (vector instanceof BitVector bitVector) { - return bitVectorFiller(bitVector, (line) -> (Boolean) line[pos]); - } + vector.endValue(rowNumber, values.size()); + }; + } - if (vector instanceof Float4Vector float4Vector) { - return float4VectorFiller(float4Vector, (line) -> (Number) line[pos]); - } - if (vector instanceof Float8Vector float8Vector) { - return float8VectorFiller(float8Vector, (line) -> (Number) line[pos]); - } + public static RowConsumer[] generateWriterPipeline(VectorSchemaRoot root, int vectorOffset, int numVectors, List resultInfos) { + Preconditions.checkArgument(vectorOffset >= 0, "Offset was negative: %s", vectorOffset); + Preconditions.checkArgument(numVectors >= 0, "Number of vectors was negative: %s", numVectors); - if (vector instanceof DateDayVector dateDayVector) { - return dateDayVectorFiller(dateDayVector, (line) -> (Number) line[pos]); - } + final RowConsumer[] builder = new RowConsumer[numVectors]; - if (vector instanceof StructVector structVector) { + for (int vecI = vectorOffset; (vecI < root.getFieldVectors().size()) && (vecI < vectorOffset + numVectors); vecI++) { + final int pos = vecI - vectorOffset; + final FieldVector vector = root.getVector(vecI); + final ResultInfo resultInfo = resultInfos.get(pos); + builder[pos] = generateVectorFiller(vector, resultInfo.getType()); - List nestedVectors = structVector.getPrimitiveVectors(); - RowConsumer [] nestedConsumers = new RowConsumer[nestedVectors.size()]; + } + return builder; - for (int i = 0; i < nestedVectors.size(); i++) { - nestedConsumers[i] = generateVectorFiller(i, nestedVectors.get(i), settings, printer); - } - return structVectorFiller(structVector, nestedConsumers, (line) -> (List) line[pos]); - } + } + + private static RowConsumer generateVectorFiller(ValueVector vector, ResultType type) { + if (type instanceof ResultType.ListT listT) { + final ValueVector nestedVector = ((ListVector) vector).getDataVector(); + + return listVectorFiller(((ListVector) vector), generateVectorFiller(nestedVector, listT.getElementType())); + } - if (vector instanceof ListVector listVector) { + return switch (((ResultType.Primitive) type)) { + case BOOLEAN -> bitVectorFiller(((BitVector) vector)); + case INTEGER -> intVectorFiller(((IntVector) vector)); + case MONEY -> moneyVectorFiller(((IntVector) vector)); + case DATE -> dateDayVectorFiller(((DateDayVector) vector)); + case NUMERIC -> float8VectorFiller((Float8Vector) vector); + case STRING -> varCharVectorFiller(((VarCharVector) vector)); + case DATE_RANGE -> dateRangeVectorFiller((StructVector) vector); - ValueVector nestedVector = listVector.getDataVector(); + }; - // pos = 0 is a workaround for now - return listVectorFiller(listVector, generateVectorFiller(0, nestedVector, settings, ((ResultPrinters.ListPrinter) printer).elementPrinter()), (line) -> (List) line[pos]); - } - throw new IllegalArgumentException("Unsupported vector type " + vector); - } + } } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowUtil.java b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowUtil.java index 7d2bc1ffcd..741885e961 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowUtil.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ArrowUtil.java @@ -2,9 +2,8 @@ import java.util.ArrayList; import java.util.List; -import java.util.function.BiFunction; -import java.util.stream.Collectors; +import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; import com.bakdata.conquery.models.types.ResultType; @@ -23,93 +22,85 @@ public class ArrowUtil { public static final RootAllocator ROOT_ALLOCATOR = new RootAllocator(); - private BiFunction fieldFor(ResultType type) { + private Field fieldFor(ResultType type, String name) { if (type instanceof ResultType.ListT) { - return ArrowUtil::listField; + return ArrowUtil.listField(name, type); } return switch (((ResultType.Primitive) type)) { - case BOOLEAN -> ArrowUtil::boolField; - case INTEGER, MONEY -> ArrowUtil::integerField; - case NUMERIC -> ArrowUtil::floatField; - case DATE -> ArrowUtil::dateField; - case DATE_RANGE -> ArrowUtil::dateRangeField; - case STRING -> ArrowUtil::stringField; + case BOOLEAN -> ArrowUtil.boolField(name); + case INTEGER -> ArrowUtil.integerField(name); + case MONEY -> ArrowUtil.moneyField(name); + case NUMERIC -> ArrowUtil.floatField(name); + case DATE -> ArrowUtil.dateField(name); + case DATE_RANGE -> ArrowUtil.dateRangeField(name); + case STRING -> ArrowUtil.stringField(name); }; } - private static Field stringField(ResultInfo info, @NonNull String uniqueName) { + private static Field stringField(@NonNull String uniqueName) { return new Field(uniqueName, FieldType.nullable(new ArrowType.Utf8()), null); } - private static Field boolField(ResultInfo info, @NonNull String uniqueName) { + private static Field boolField(@NonNull String uniqueName) { return new Field(uniqueName, FieldType.nullable(ArrowType.Bool.INSTANCE), null); } - private static Field integerField(ResultInfo info, @NonNull String uniqueName) { + private static Field integerField(@NonNull String uniqueName) { return new Field(uniqueName, FieldType.nullable(new ArrowType.Int(32, true)), null); } - private static Field floatField(ResultInfo info, @NonNull String uniqueName) { + private static Field moneyField(@NonNull String uniqueName) { + /*TODO FK + use decimal: new Field(uniqueName, FieldType.nullable(new ArrowType.Decimal(38 - scale, scale, 128)), null); + This will also impact Frontend preview, and ExternalFormBackends, needs planning. + Note: I suspect jsArrow has a bug, where it reads Decimal as BigInt + */ + return new Field(uniqueName, FieldType.nullable(new ArrowType.Int(32, true)), null); + + } + + private static Field floatField(@NonNull String uniqueName) { return new Field(uniqueName, FieldType.nullable(new ArrowType.FloatingPoint(FloatingPointPrecision.DOUBLE)), null); } - private static Field dateField(ResultInfo info, @NonNull String uniqueName) { + private static Field dateField(@NonNull String uniqueName) { return new Field(uniqueName, FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null); } - private static Field dateRangeField(ResultInfo info, @NonNull String uniqueName) { + private static Field dateRangeField(@NonNull String uniqueName) { return new Field( uniqueName, FieldType.nullable(ArrowType.Struct.INSTANCE), List.of( - dateField(info, "min"), - dateField(info, "max") + dateField("min"), + dateField("max") )); } - private static Field listField(ResultInfo info, @NonNull String uniqueName) { - if (!(info.getType() instanceof ResultType.ListT)) { - throw new IllegalStateException("Expected result type of " + ResultType.ListT.class.getName() + " but got " + info.getType().getClass().getName()); - } - - final ResultType elementType = ((ResultType.ListT) info.getType()).getElementType(); - BiFunction nestedFieldCreator = fieldFor(elementType); - final Field nestedField = nestedFieldCreator.apply(info, uniqueName); - return new Field( - uniqueName, - FieldType.nullable(ArrowType.List.INSTANCE), - List.of(nestedField) - ); - } - - /** - * Creates an arrow field vector (a column) corresponding to the internal conquery type and initializes the column with - * a localized header. - * @param info internal meta data for the result column - * @param collector to create unique names across the columns - * @return a Field (the arrow representation of the column) - */ - public Field createField(ResultInfo info, UniqueNamer collector) { - // Fallback to string field if type is not explicitly registered - BiFunction fieldCreator = fieldFor(info.getType()); - return fieldCreator.apply(info, collector.getUniqueName(info)); + private static Field listField(@NonNull String uniqueName, ResultType type) { + final ResultType elementType = ((ResultType.ListT) type).getElementType(); + final Field nestedField = fieldFor(elementType, uniqueName); + + return new Field(uniqueName, FieldType.nullable(ArrowType.List.INSTANCE), List.of(nestedField)); } - public static List generateFields(@NonNull List info, UniqueNamer collector) { + public static List generateFields(@NonNull List info, UniqueNamer collector, PrintSettings printSettings) { return info.stream() - .map(i -> createField(i, collector)) - .collect(Collectors.toUnmodifiableList()); + .map(i -> fieldFor(i.getType(), collector.getUniqueName(i, printSettings))) + .toList(); } @NotNull - public static List generateFields(List idHeaders, List resultInfo, UniqueNamer uniqueNamer) { + public static List generateFields(List idHeaders, List resultInfo, UniqueNamer uniqueNamer, PrintSettings printSettings) { // Combine id and value Fields to one vector to build a schema - final List idFields = generateFields(idHeaders, uniqueNamer); - List fields = new ArrayList<>(idFields); - fields.addAll(generateFields(resultInfo, uniqueNamer)); + List fields = new ArrayList<>(); + + fields.addAll(generateFields(idHeaders, uniqueNamer, printSettings)); + fields.addAll(generateFields(resultInfo, uniqueNamer, printSettings)); + return fields; } } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ResultArrowProcessor.java b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ResultArrowProcessor.java index 7e2c02ada1..376d1dcb17 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ResultArrowProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/ResultArrowProcessor.java @@ -23,6 +23,7 @@ import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.SingleTableResult; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; +import com.bakdata.conquery.models.query.resultinfo.printers.ArrowResultPrinters; import com.bakdata.conquery.models.worker.DatasetRegistry; import com.bakdata.conquery.models.worker.Namespace; import com.bakdata.conquery.util.io.ConqueryMDC; @@ -99,8 +100,8 @@ public static Response getArrow // Collect ResultInfos for id columns and result columns - final List resultInfosId = config.getIdColumns().getIdResultInfos(settings); - final List resultInfosExec = exec.getResultInfos(settings); + final List resultInfosId = config.getIdColumns().getIdResultInfos(); + final List resultInfosExec = exec.getResultInfos(); StreamingOutput out = output -> { try { @@ -110,7 +111,7 @@ public static Response getArrow arrowConfig, resultInfosId, resultInfosExec, - exec.streamResults(limit) + exec.streamResults(limit), new ArrowResultPrinters() ); } finally { diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/RowConsumer.java b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/RowConsumer.java index 9c9d27a5af..057a98306b 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/arrow/RowConsumer.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/arrow/RowConsumer.java @@ -1,7 +1,5 @@ package com.bakdata.conquery.io.result.arrow; -import java.util.Objects; - @FunctionalInterface public interface RowConsumer { @@ -10,23 +8,6 @@ public interface RowConsumer { * * @param t the input argument */ - void accept(int rowNumber, Object[] row); - - /** - * Returns a composed {@code Consumer} that performs, in sequence, this - * operation followed by the {@code after} operation. If performing either - * operation throws an exception, it is relayed to the caller of the - * composed operation. If performing this operation throws an exception, - * the {@code after} operation will not be performed. - * - * @param after the operation to perform after this operation - * @return a composed {@code Consumer} that performs in sequence this - * operation followed by the {@code after} operation - * @throws NullPointerException if {@code after} is null - */ - default RowConsumer andThen(RowConsumer after) { - Objects.requireNonNull(after); - return (n, r) -> { accept(n, r); after.accept(n, r); }; - } + void accept(int rowNumber, Object value); } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java b/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java index 295df2b14a..a9eac207ff 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/csv/CsvRenderer.java @@ -9,6 +9,9 @@ import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.StringResultPrinters; import com.bakdata.conquery.models.query.results.EntityResult; import com.univocity.parsers.csv.CsvWriter; import lombok.RequiredArgsConstructor; @@ -22,36 +25,46 @@ public class CsvRenderer { private final CsvWriter writer; private final PrintSettings cfg; - public void toCSV(List idHeaders, List infos, Stream resultStream) { + public void toCSV(List idHeaders, List infos, Stream resultStream, PrintSettings printSettings) { UniqueNamer uniqNamer = new UniqueNamer(cfg); - final String[] headers = Stream.concat(idHeaders.stream(), infos.stream()).map(uniqNamer::getUniqueName).toArray(String[]::new); + final String[] headers = Stream.concat(idHeaders.stream(), infos.stream()).map(info -> uniqNamer.getUniqueName(info, printSettings)).toArray(String[]::new); writer.writeHeaders(headers); - createCSVBody(cfg, infos, resultStream); + createCSVBody(cfg, infos, resultStream, printSettings, new StringResultPrinters()); } - private void createCSVBody(PrintSettings cfg, List infos, Stream results) { + private void createCSVBody(PrintSettings cfg, List infos, Stream results, PrintSettings printSettings, + PrinterFactory printerFactory) { + final Printer[] printers = infos.stream().map(info -> info.createPrinter(printerFactory, printSettings)).toArray(Printer[]::new); + results.map(result -> Pair.of(cfg.getIdMapper().map(result), result)) .sorted(Map.Entry.comparingByKey()) .forEach(res -> res .getValue() .streamValues() - .forEach(result -> printLine(res.getKey(), infos, result))); + .forEach(result -> printLine(res.getKey(), printers, result))); } - public void printLine(EntityPrintId entity, List infos, Object[] value) { + public void printLine(EntityPrintId entity, Printer[] printers, Object[] values) { // Cast here to Object[] so it is clear to intellij that the varargs call is intended writer.addValues((Object[]) entity.getExternalId()); try { - for (int i = 0; i < infos.size(); i++) { - writer.addValue(infos.get(i).printNullable(value[i])); + for (int i = 0; i < printers.length; i++) { + final Object value = values[i]; + + if (value == null) { + writer.addValue(""); + continue; + } + + writer.addValue(printers[i].apply(value)); } } catch (Exception e) { - throw new IllegalStateException("Unable to print line " + Arrays.deepToString(value), e); + throw new IllegalStateException("Unable to print line " + Arrays.deepToString(values), e); } writer.writeValuesToRow(); diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/csv/ResultCsvProcessor.java b/backend/src/main/java/com/bakdata/conquery/io/result/csv/ResultCsvProcessor.java index 0eb59cca95..261ca45f1e 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/csv/ResultCsvProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/csv/ResultCsvProcessor.java @@ -62,7 +62,7 @@ public Response createResult(Su final StreamingOutput out = os -> { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, charset))) { final CsvRenderer renderer = new CsvRenderer(config.getCsv().createWriter(writer), settings); - renderer.toCSV(config.getIdColumns().getIdResultInfos(settings), exec.getResultInfos(settings), exec.streamResults(limit)); + renderer.toCSV(config.getIdColumns().getIdResultInfos(), exec.getResultInfos(), exec.streamResults(limit), settings); } catch (EofException e) { log.trace("User canceled download"); diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/excel/ExcelRenderer.java b/backend/src/main/java/com/bakdata/conquery/io/result/excel/ExcelRenderer.java index 71e10f3ae1..ec29adb030 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/excel/ExcelRenderer.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/excel/ExcelRenderer.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.io.OutputStream; import java.math.BigDecimal; +import java.time.LocalDate; import java.util.List; import java.util.Map; import java.util.OptionalLong; @@ -12,14 +13,17 @@ import c10n.C10N; import com.bakdata.conquery.internationalization.ExcelSheetNameC10n; import com.bakdata.conquery.models.auth.entities.User; -import com.bakdata.conquery.models.common.CDate; import com.bakdata.conquery.models.config.ExcelConfig; import com.bakdata.conquery.models.execution.ManagedExecution; import com.bakdata.conquery.models.i18n.I18n; +import com.bakdata.conquery.models.identifiable.mapping.PrintIdMapper; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.SingleTableResult; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; +import com.bakdata.conquery.models.query.resultinfo.printers.ExcelResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.types.ResultType; import com.google.common.collect.ImmutableMap; @@ -42,60 +46,35 @@ public class ExcelRenderer { public static final int MAX_LINES = 1_048_576; - - private static TypeWriter writer(ResultType type) { - if(!(type instanceof ResultType.Primitive)){ - //Excel cannot handle complex types so we just toString them. - return (info, settings, cell, value, styles) -> writeStringCell(info, cell, value, styles); - } - - return switch (((ResultType.Primitive) type)) { - case BOOLEAN -> (info, settings, cell, value, styles) -> writeBooleanCell(info, cell, value, styles); - case INTEGER -> ExcelRenderer::writeIntegerCell; - case MONEY -> ExcelRenderer::writeMoneyCell; - case NUMERIC -> ExcelRenderer::writeNumericCell; - case DATE -> ExcelRenderer::writeDateCell; - default -> (info, settings, cell, value, styles) -> writeStringCell(info, cell, value, styles); - }; - } - public static final int CHARACTER_WIDTH_DIVISOR = 256; public static final int AUTOFILTER_SPACE_WIDTH = 3; - private final SXSSFWorkbook workbook; private final ExcelConfig config; - private final PrintSettings cfg; + private final PrintSettings settings; private final ImmutableMap styles; - - - public ExcelRenderer(ExcelConfig config, PrintSettings cfg) { + public ExcelRenderer(ExcelConfig config, PrintSettings settings) { workbook = new SXSSFWorkbook(); this.config = config; - styles = config.generateStyles(workbook, cfg); - this.cfg = cfg; - } - - @FunctionalInterface - private interface TypeWriter { - void writeCell(ResultInfo info, PrintSettings settings, Cell cell, Object value, Map styles); + styles = config.generateStyles(workbook, settings); + this.settings = settings; } public void renderToStream(List idHeaders, E exec, OutputStream outputStream, OptionalLong limit, PrintSettings printSettings) throws IOException { - final List resultInfosExec = exec.getResultInfos(printSettings); + final List resultInfosExec = exec.getResultInfos(); setMetaData(exec); - SXSSFSheet sheet = workbook.createSheet(C10N.get(ExcelSheetNameC10n.class, I18n.LOCALE.get()).result()); + final SXSSFSheet sheet = workbook.createSheet(C10N.get(ExcelSheetNameC10n.class, I18n.LOCALE.get()).result()); try { sheet.setDefaultColumnWidth(config.getDefaultColumnWidth()); // Create a table environment inside the excel sheet - XSSFTable table = createTableEnvironment(exec, sheet); + final XSSFTable table = createTableEnvironment(exec, sheet); - writeHeader(sheet, idHeaders, resultInfosExec, table); + writeHeader(sheet, idHeaders, resultInfosExec, table, printSettings); - int writtenLines = writeBody(sheet, resultInfosExec, exec.streamResults(OptionalLong.of(limit.orElse(MAX_LINES)))); + final int writtenLines = writeBody(sheet, resultInfosExec, exec.streamResults(OptionalLong.of(limit.orElse(MAX_LINES))), new ExcelResultPrinters()); postProcessTable(sheet, table, writtenLines, idHeaders.size()); @@ -121,40 +100,18 @@ private void setMetaData(E exec extendedProperties.setApplication(config.getApplicationName()); } - /** - * Do postprocessing on the result to improve the visuals: - * - Set the area of the table environment - * - Freeze the id columns - * - Add autofilters (not for now) - */ - private void postProcessTable(SXSSFSheet sheet, XSSFTable table, int writtenLines, int size) { - // Extend the table area to the added data - CellReference topLeft = new CellReference(0, 0); - - // The area must be at least a header row and a data row. If no line was written we include an empty data row so POI is happy - CellReference bottomRight = new CellReference(Math.max(1, writtenLines), table.getColumnCount() - 1); - AreaReference newArea = new AreaReference(topLeft, bottomRight, workbook.getSpreadsheetVersion()); - table.setArea(newArea); - - // Add auto filters. This must be done on the lower level CTTable. Using SXSSFSheet::setAutoFilter will corrupt the table - table.getCTTable().addNewAutoFilter(); - - // Freeze Header and id columns - sheet.createFreezePane(size, 1); - } - /** * Create a table environment, which improves mainly the visuals of the produced table. */ @NotNull private XSSFTable createTableEnvironment(ManagedExecution exec, SXSSFSheet sheet) { - XSSFTable table = sheet.getWorkbook().getXSSFWorkbook().getSheet(sheet.getSheetName()).createTable(null); + final XSSFTable table = sheet.getWorkbook().getXSSFWorkbook().getSheet(sheet.getSheetName()).createTable(null); - CTTable cttable = table.getCTTable(); + final CTTable cttable = table.getCTTable(); table.setName(exec.getLabelWithoutAutoLabelSuffix()); cttable.setTotalsRowShown(false); - CTTableStyleInfo styleInfo = cttable.addNewTableStyleInfo(); + final CTTableStyleInfo styleInfo = cttable.addNewTableStyleInfo(); // Not sure how important this name is styleInfo.setName("TableStyleMedium2"); styleInfo.setShowColumnStripes(false); @@ -170,24 +127,24 @@ private void writeHeader( SXSSFSheet sheet, List idHeaders, List infos, - XSSFTable table) { + XSSFTable table, PrintSettings printSettings) { - CTTableColumns columns = table.getCTTable().addNewTableColumns(); + final CTTableColumns columns = table.getCTTable().addNewTableColumns(); columns.setCount(idHeaders.size() + infos.size()); - UniqueNamer uniqueNamer = new UniqueNamer(cfg); + final UniqueNamer uniqueNamer = new UniqueNamer(settings); { - Row header = sheet.createRow(0); + final Row header = sheet.createRow(0); // First to create the columns and track them for auto size before the first row is written int currentColumn = 0; for (ResultInfo idHeader : idHeaders) { - CTTableColumn column = columns.addNewTableColumn(); + final CTTableColumn column = columns.addNewTableColumn(); // Table column ids MUST be set and MUST start at 1, excel will fail otherwise column.setId(currentColumn + 1); - final String uniqueName = uniqueNamer.getUniqueName(idHeader); + final String uniqueName = uniqueNamer.getUniqueName(idHeader, printSettings); column.setName(uniqueName); - Cell headerCell = header.createCell(currentColumn); + final Cell headerCell = header.createCell(currentColumn); headerCell.setCellValue(uniqueName); // Track column explicitly, because sheet.trackAllColumnsForAutoSizing() does not work with @@ -198,12 +155,12 @@ private void writeHeader( } for (ResultInfo info : infos) { - final String columnName = uniqueNamer.getUniqueName(info); - CTTableColumn column = columns.addNewTableColumn(); + final String columnName = uniqueNamer.getUniqueName(info, printSettings); + final CTTableColumn column = columns.addNewTableColumn(); column.setId(currentColumn + 1); column.setName(columnName); - Cell headerCell = header.createCell(currentColumn); + final Cell headerCell = header.createCell(currentColumn); headerCell.setCellValue(columnName); sheet.trackColumnForAutoSizing(currentColumn); @@ -216,11 +173,15 @@ private void writeHeader( private int writeBody( SXSSFSheet sheet, List infos, - Stream resultLines) { + Stream resultLines, PrinterFactory printerFactory) { // Row 0 is the Header the data starts at 1 final AtomicInteger currentRow = new AtomicInteger(1); - final int writtenLines = resultLines.mapToInt(l -> this.writeRowsForEntity(infos, l, currentRow, cfg, sheet)).sum(); + + final TypeWriter[] writers = infos.stream().map(info -> writer(info.getType(), info.createPrinter(printerFactory, settings), settings)).toArray(TypeWriter[]::new); + final PrintIdMapper idMapper = settings.getIdMapper(); + + final int writtenLines = resultLines.mapToInt(l -> writeRowsForEntity(infos, l, currentRow, sheet, writers, idMapper)).sum(); // The result was shorter than the number of rows to track, so we auto size here explicitly if (writtenLines < config.getLastRowToAutosize()) { @@ -230,44 +191,65 @@ private int writeBody( return writtenLines; } + /** + * Do postprocessing on the result to improve the visuals: + * - Set the area of the table environment + * - Freeze the id columns + * - Add autofilters (not for now) + */ + private void postProcessTable(SXSSFSheet sheet, XSSFTable table, int writtenLines, int size) { + // Extend the table area to the added data + final CellReference topLeft = new CellReference(0, 0); + + // The area must be at least a header row and a data row. If no line was written we include an empty data row so POI is happy + final CellReference bottomRight = new CellReference(Math.max(1, writtenLines), table.getColumnCount() - 1); + final AreaReference newArea = new AreaReference(topLeft, bottomRight, workbook.getSpreadsheetVersion()); + table.setArea(newArea); + + // Add auto filters. This must be done on the lower level CTTable. Using SXSSFSheet::setAutoFilter will corrupt the table + table.getCTTable().addNewAutoFilter(); + + // Freeze Header and id columns + sheet.createFreezePane(size, 1); + } + /** * Writes the result lines for each entity. */ - private int writeRowsForEntity( - List infos, - EntityResult internalRow, - final AtomicInteger currentRow, - PrintSettings settings, - SXSSFSheet sheet) { - String[] ids = settings.getIdMapper().map(internalRow).getExternalId(); + private int writeRowsForEntity(List infos, EntityResult internalRow, final AtomicInteger currentRow, SXSSFSheet sheet, TypeWriter[] writers, PrintIdMapper idMapper) { + + final String[] ids = idMapper.map(internalRow).getExternalId(); int writtenLines = 0; - for (Object[] resultValues : internalRow.listResultLines()) { + for (Object[] line : internalRow.listResultLines()) { final int thisRow = currentRow.getAndIncrement(); - Row row = sheet.createRow(thisRow); + final Row row = sheet.createRow(thisRow); + // Write id cells int currentColumn = 0; + for (String id : ids) { - Cell idCell = row.createCell(currentColumn); + final Cell idCell = row.createCell(currentColumn); idCell.setCellValue(id); currentColumn++; } // Write data cells - for (int i = 0; i < infos.size(); i++) { - ResultInfo resultInfo = infos.get(i); - Object resultValue = resultValues[i]; - Cell dataCell = row.createCell(currentColumn); + for (int index = 0; index < infos.size(); index++) { + final Object value = line[index]; + final Cell dataCell = row.createCell(currentColumn); currentColumn++; - if (resultValue == null) { + + if (value == null) { continue; } + // Fallback to string if type is not explicitly registered - TypeWriter typeWriter = writer(resultInfo.getType()); + final TypeWriter typeWriter = writers[index]; - typeWriter.writeCell(resultInfo, settings, dataCell, resultValue, styles); + typeWriter.writeCell(value, dataCell, styles); } if (thisRow == config.getLastRowToAutosize()) { @@ -302,57 +284,66 @@ private void setColumnWidthsAndUntrack(SXSSFSheet sheet) { } } + private static TypeWriter writer(ResultType type, Printer printer, PrintSettings settings) { + if (type instanceof ResultType.ListT) { + //Excel cannot handle LIST types so we just toString them. + return (value, cell, styles) -> writeStringCell(cell, value, printer); + } + + return switch (((ResultType.Primitive) type)) { + case BOOLEAN -> (value, cell, styles) -> writeBooleanCell(value, cell, printer); + case INTEGER -> (value, cell, styles) -> writeIntegerCell(value, cell, printer, styles); + case MONEY -> (value, cell, styles) -> writeMoneyCell(value, cell, printer, settings, styles); + case NUMERIC -> (value, cell, styles) -> writeNumericCell(value, cell, printer, styles); + case DATE -> (value, cell, styles) -> writeDateCell(value, cell, printer, styles); + default -> (value, cell, styles) -> writeStringCell(cell, value, printer); + }; + } + // Type specific cell writers - private static void writeStringCell(ResultInfo info, Cell cell, Object value, Map styles) { - cell.setCellValue( - info.printNullable( - value - )); + private static void writeStringCell(Cell cell, Object value, Printer printer) { + cell.setCellValue((String) printer.apply(value)); } /** * This writer is only used on Columns with the result type {@link ResultType.Primitive#BOOLEAN}, not on complex types such as `LIST[BOOLEAN]`, * because MS Excel can only represent those as strings */ - private static void writeBooleanCell(ResultInfo info, Cell cell, Object value, Map styles) { - if (value instanceof Boolean aBoolean) { - cell.setCellValue(aBoolean); - return; - } - cell.setCellValue(info.printNullable(value)); + private static void writeBooleanCell(Object value, Cell cell, Printer printer) { + cell.setCellValue((Boolean) printer.apply(value)); } - private static void writeDateCell(ResultInfo info, PrintSettings settings, Cell cell, Object value, Map styles) { - if (!(value instanceof Number)) { - throw new IllegalStateException(String.format("`%s` Expected an Number but got an '%s' with the value: %s", - info, - value != null ? value.getClass().getName() : "no type", value - )); - } - cell.setCellValue(CDate.toLocalDate(((Number) value).intValue())); - cell.setCellStyle(styles.get(ExcelConfig.DATE_STYLE)); - } - - public static void writeIntegerCell(ResultInfo info, PrintSettings settings, Cell cell, Object value, Map styles) { - cell.setCellValue(((Number) value).longValue()); + public static void writeIntegerCell(Object value, Cell cell, Printer printer, Map styles) { + cell.setCellValue(((Number) printer.apply(value)).longValue()); cell.setCellStyle(styles.get(ExcelConfig.INTEGER_STYLE)); } - public static void writeNumericCell(ResultInfo info, PrintSettings settings, Cell cell, Object value, Map styles) { - cell.setCellValue(((Number) value).doubleValue()); - cell.setCellStyle(styles.get(ExcelConfig.NUMERIC_STYLE)); - } + public static void writeMoneyCell(Object valueRaw, Cell cell, Printer printer, PrintSettings settings, Map styles) { + + final BigDecimal value = (BigDecimal) printer.apply(valueRaw); - public static void writeMoneyCell(ResultInfo info, PrintSettings settings, Cell cell, Object value, Map styles) { - CellStyle currencyStyle = styles.get(ExcelConfig.CURRENCY_STYLE_PREFIX + settings.getCurrency().getCurrencyCode()); + final CellStyle currencyStyle = styles.get(ExcelConfig.CURRENCY_STYLE_PREFIX + settings.getCurrency().getCurrencyCode()); if (currencyStyle == null) { - // Print as cents or what ever the minor currency unit is - cell.setCellValue(value.toString()); + // Print as cents or whatever the minor currency unit is + cell.setCellValue(value.movePointRight(settings.getCurrency().getDefaultFractionDigits()).intValue()); return; } cell.setCellStyle(currencyStyle); - cell.setCellValue( - new BigDecimal(((Number) value).longValue()).movePointLeft(settings.getCurrency().getDefaultFractionDigits()).doubleValue() - ); + cell.setCellValue(value.doubleValue()); + } + + public static void writeNumericCell(Object value, Cell cell, Printer printer, Map styles) { + cell.setCellValue(((Number) printer.apply(value)).doubleValue()); + cell.setCellStyle(styles.get(ExcelConfig.NUMERIC_STYLE)); + } + + private static void writeDateCell(Object value, Cell cell, Printer printer, Map styles) { + cell.setCellValue((LocalDate) printer.apply(value)); + cell.setCellStyle(styles.get(ExcelConfig.DATE_STYLE)); + } + + @FunctionalInterface + private interface TypeWriter { + void writeCell(Object value, Cell cell, Map styles); } } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/excel/ResultExcelProcessor.java b/backend/src/main/java/com/bakdata/conquery/io/result/excel/ResultExcelProcessor.java index 89194e75c8..cb0c79d25c 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/excel/ResultExcelProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/excel/ResultExcelProcessor.java @@ -57,7 +57,7 @@ public Response createResult(Su final ExcelRenderer excelRenderer = new ExcelRenderer(excelConfig, settings); final StreamingOutput out = output -> { - excelRenderer.renderToStream(conqueryConfig.getIdColumns().getIdResultInfos(settings), exec, output, limit, settings); + excelRenderer.renderToStream(conqueryConfig.getIdColumns().getIdResultInfos(), exec, output, limit, settings); log.trace("FINISHED downloading {}", exec.getId()); }; diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/parquet/EntityResultWriteSupport.java b/backend/src/main/java/com/bakdata/conquery/io/result/parquet/EntityResultWriteSupport.java index 8dcad2291d..387eadbb09 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/parquet/EntityResultWriteSupport.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/parquet/EntityResultWriteSupport.java @@ -1,19 +1,20 @@ package com.bakdata.conquery.io.result.parquet; -import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import com.bakdata.conquery.io.result.arrow.ArrowUtil; -import com.bakdata.conquery.models.common.CDate; +import com.bakdata.conquery.models.common.daterange.CDateRange; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.ArrowResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.query.results.MultilineEntityResult; import com.bakdata.conquery.models.types.ResultType; -import lombok.Data; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.arrow.vector.types.pojo.Schema; @@ -24,6 +25,7 @@ import org.apache.parquet.io.api.Binary; import org.apache.parquet.io.api.RecordConsumer; import org.apache.parquet.schema.MessageType; +import org.jetbrains.annotations.NotNull; /** * {@link WriteSupport} for Conquery's {@link EntityResult} type. @@ -40,14 +42,69 @@ public class EntityResultWriteSupport extends WriteSupport { private final PrintSettings printSettings; private MessageType schema; - private List columnConsumer; + private List columnConsumers; + private List columnPrinters; private RecordConsumer recordConsumer; + /** + * Generates the parquet schema format from the {@link ResultInfo}s of a query + * + * @param idHeaders {@link ResultInfo} for the Ids + * @param resultValueInfos {@link ResultInfo} for the result values + * @param uniqueNamer A column namer for the fields in the schema + * @param printSettings1 + * @return the parquet schema + */ + public static MessageType generateSchema(List idHeaders, List resultValueInfos, UniqueNamer uniqueNamer, PrintSettings printSettings1) { + /* + Because Parquet Schemas rely on primitive types with logical annotations + which are tedious to configure, we take the detour over the arrow schema. + */ + final SchemaMapping schemaMapping = + new SchemaConverter().fromArrow(new Schema(ArrowUtil.generateFields(idHeaders, resultValueInfos, uniqueNamer, printSettings1))); + + return schemaMapping.getParquetSchema(); + + } + + private static List generateColumnConsumers(List idHeaders, List resultInfos) { + return Stream.concat(idHeaders.stream(), resultInfos.stream()) + .map(ResultInfo::getType) + .map(EntityResultWriteSupport::columnConsumerForType) + .toList(); + + } + + private static List generateColumnPrinters(List idHeaders, List resultInfos, PrintSettings printSettings, PrinterFactory printerFactory) { + + return Stream.concat(idHeaders.stream(), resultInfos.stream()) + .map(info -> info.createPrinter(printerFactory, printSettings)) + .toList(); + + } + + private static ColumnConsumer columnConsumerForType(ResultType resultType) { + + if (resultType instanceof ResultType.ListT listT) { + return new ListColumnConsumer(columnConsumerForType(listT.getElementType())); + } + + return switch (((ResultType.Primitive) resultType)) { + case BOOLEAN -> new BooleanColumnConsumer(); + case INTEGER, DATE -> new IntegerColumnConsumer(); + case NUMERIC -> new NumericColumnConsumer(); + case MONEY -> new MoneyColumnConsumer(); + case DATE_RANGE -> new DateRangeColumnConsumer(); + case STRING -> new StringColumnConsumer(); + }; + } + @Override public WriteContext init(Configuration configuration) { - schema = generateSchema(idHeaders, resultInfo, new UniqueNamer(printSettings)); - columnConsumer = generateColumnConsumers(idHeaders, resultInfo, printSettings); + schema = generateSchema(idHeaders, resultInfo, new UniqueNamer(printSettings), printSettings); + columnConsumers = generateColumnConsumers(idHeaders, resultInfo); + columnPrinters = generateColumnPrinters(idHeaders, resultInfo, printSettings, new ArrowResultPrinters()); return new WriteContext(schema, Map.of()); } @@ -65,32 +122,45 @@ public void write(EntityResult record) { // This should not happen because of the workaround in ParquetRenderer log.warn("Processing a MultilineEntityResult is not working properly. Only the first line will be output"); } + + // Write ID fields + final Object[] printedExternalId = getPrintedExternalId(record); + for (Object[] listResultLine : listResultLines) { recordConsumer.startMessage(); - // Write ID fields - final String[] externalId = printSettings.getIdMapper().map(record).getExternalId(); - int cellIdx = 0; - for (int i = 0; i < externalId.length; i++, cellIdx++) { - final String subId = externalId[i]; - if (subId == null) { + + for (int index = 0; index < printedExternalId.length; index++) { + final Object printed = printedExternalId[index]; + if (printed == null) { continue; } - final String fieldName = schema.getFieldName(cellIdx); - recordConsumer.startField(fieldName, cellIdx); - columnConsumer.get(cellIdx).accept(recordConsumer, subId); - recordConsumer.endField(fieldName, cellIdx); + + final String fieldName = schema.getFieldName(index); + + recordConsumer.startField(fieldName, index); + columnConsumers.get(index).accept(recordConsumer, printed); + recordConsumer.endField(fieldName, index); } // Write Result fields - for (int i = 0; i < resultInfo.size(); i++, cellIdx++) { - final Object resultValue = listResultLine[i]; - if (resultValue == null) { + for (int index = 0; index < listResultLine.length; index++) { + final int colId = index + printedExternalId.length; + + final Object value = listResultLine[index]; + + if (value == null) { + // Parquet consumers cannot handle null? continue; } - final String fieldName = schema.getFieldName(cellIdx); - recordConsumer.startField(fieldName, cellIdx); - columnConsumer.get(cellIdx).accept(recordConsumer, resultValue); - recordConsumer.endField(fieldName, cellIdx); + + Printer printer = columnPrinters.get(colId); + final Object printed = printer.apply(value); + + final String fieldName = schema.getFieldName(colId); + + recordConsumer.startField(fieldName, colId); + columnConsumers.get(colId).accept(recordConsumer, printed); + recordConsumer.endField(fieldName, colId); } recordConsumer.endMessage(); @@ -98,102 +168,86 @@ public void write(EntityResult record) { } - /** - * Generates the parquet schema format from the {@link ResultInfo}s of a query - * - * @param idHeaders {@link ResultInfo} for the Ids - * @param resultValueInfos {@link ResultInfo} for the result values - * @param uniqueNamer A column namer for the fields in the schema - * @return the parquet schema - */ - public static MessageType generateSchema( - List idHeaders, - List resultValueInfos, UniqueNamer uniqueNamer) { + @NotNull + private Object[] getPrintedExternalId(EntityResult record) { + final String[] externalId = printSettings.getIdMapper().map(record).getExternalId(); - /* - Because Parquet Schemas rely on primitive types with logical annotations - which are tedious to configure, we take the detour over the arrow schema. - */ - final SchemaMapping schemaMapping = new SchemaConverter().fromArrow(new Schema(ArrowUtil.generateFields(idHeaders, resultValueInfos, uniqueNamer))); - - return schemaMapping.getParquetSchema(); + final Object[] printedExternalId = new String[externalId.length]; + for (int index = 0; index < externalId.length; index++) { + Printer printer = columnPrinters.get(index); + printedExternalId[index] = printer.apply(externalId[index]); + } + return printedExternalId; } - @Data - private static class StringTColumnConsumer implements ColumnConsumer { - - private final ResultPrinters.Printer printer; - private final PrintSettings printSettings; + private record StringColumnConsumer() implements ColumnConsumer { @Override public void accept(RecordConsumer recordConsumer, Object o) { - final String printValue = getPrinter().print(o); - recordConsumer.addBinary(Binary.fromString(printValue)); + recordConsumer.addBinary(Binary.fromString((String) o)); } } - @RequiredArgsConstructor - private static class BooleanTColumnConsumer implements ColumnConsumer { - + private record BooleanColumnConsumer() implements ColumnConsumer { @Override public void accept(RecordConsumer recordConsumer, Object o) { recordConsumer.addBoolean((boolean) o); } } - @RequiredArgsConstructor - private static class IntegerTColumnConsumer implements ColumnConsumer { + private record IntegerColumnConsumer() implements ColumnConsumer { @Override public void accept(RecordConsumer recordConsumer, Object o) { - recordConsumer.addInteger((int) o); + recordConsumer.addInteger(((Number) o).intValue()); } } - @RequiredArgsConstructor - private static class NumericTColumnConsumer implements ColumnConsumer { + + private record NumericColumnConsumer() implements ColumnConsumer { @Override public void accept(RecordConsumer recordConsumer, Object o) { - recordConsumer.addDouble((double) o); + recordConsumer.addDouble(((Number) o).doubleValue()); } } - @RequiredArgsConstructor - private static class DateRangeTColumnConsumer implements ColumnConsumer { - private final static String MIN_FIELD_NAME = "min"; - private final static String MAX_FIELD_NAME = "max"; - + private record MoneyColumnConsumer() implements ColumnConsumer { @Override public void accept(RecordConsumer recordConsumer, Object o) { - List dateRange = (List) o; - recordConsumer.startGroup(); - Integer min = dateRange.get(0); + recordConsumer.addInteger(((Integer) o)); + } + } + + + private record DateRangeColumnConsumer() implements ColumnConsumer { + private static final String MIN_FIELD_NAME = "min"; + private static final String MAX_FIELD_NAME = "max"; + @Override + public void accept(RecordConsumer recordConsumer, Object o) { + final CDateRange dateRange = (CDateRange) o; + recordConsumer.startGroup(); - if (min != null && !(CDate.isNegativeInfinity(min))) { + if (dateRange.hasLowerBound()) { recordConsumer.startField(MIN_FIELD_NAME, 0); - recordConsumer.addInteger(min); + recordConsumer.addInteger(dateRange.getMinValue()); recordConsumer.endField(MIN_FIELD_NAME, 0); } - Integer max = dateRange.get(1); - if (max != null && !(CDate.isPositiveInfinity(max))) { + if (dateRange.hasUpperBound()) { recordConsumer.startField(MAX_FIELD_NAME, 1); - recordConsumer.addInteger(max); + recordConsumer.addInteger(dateRange.getMaxValue()); recordConsumer.endField(MAX_FIELD_NAME, 1); } + recordConsumer.endGroup(); } } - @RequiredArgsConstructor - private static class ListTColumnConsumer implements ColumnConsumer { - - private final ColumnConsumer elementConsumer; - private final PrintSettings printSettings; + private record ListColumnConsumer(ColumnConsumer elementConsumer) implements ColumnConsumer { @Override public void accept(RecordConsumer recordConsumer, Object o) { @@ -207,7 +261,7 @@ public void accept(RecordConsumer recordConsumer, Object o) { return; } - // This nesting is wierd but documented https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#lists + // This nesting is weird but documented https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#lists recordConsumer.startGroup(); recordConsumer.startField("list", 0); for (Object elem : list) { @@ -221,31 +275,4 @@ public void accept(RecordConsumer recordConsumer, Object o) { recordConsumer.endGroup(); } } - - private static List generateColumnConsumers(List idHeaders, List resultInfos, PrintSettings printSettings) { - final List consumers = new ArrayList<>(); - for (ResultInfo idHeader : idHeaders) { - consumers.add(getForResultType(idHeader.getType(), idHeader.getPrinter(), printSettings)); - } - - for (ResultInfo resultInfo : resultInfos) { - consumers.add(getForResultType(resultInfo.getType(), resultInfo.getPrinter(), printSettings)); - } - return consumers; - } - - private static ColumnConsumer getForResultType(ResultType resultType, ResultPrinters.Printer printer, PrintSettings printSettings) { - - if (resultType instanceof ResultType.ListT listT) { - return new ListTColumnConsumer(getForResultType(listT.getElementType(), ((ResultPrinters.ListPrinter) printer).elementPrinter(), printSettings), printSettings); - } - - return switch (((ResultType.Primitive) resultType)) { - case BOOLEAN -> new BooleanTColumnConsumer(); - case INTEGER, DATE, MONEY -> new IntegerTColumnConsumer(); - case NUMERIC -> new NumericTColumnConsumer(); - case DATE_RANGE -> new DateRangeTColumnConsumer(); - case STRING -> new StringTColumnConsumer(printer, printSettings); - }; - } } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ParquetRenderer.java b/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ParquetRenderer.java index 12dcb2bbe2..a903133ff6 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ParquetRenderer.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ParquetRenderer.java @@ -24,6 +24,50 @@ @UtilityClass public class ParquetRenderer { + public static void writeToStream( + OutputStream outputStream, + List idHeaders, + List resultInfo, + PrintSettings printSettings, + Stream results) throws IOException { + + // Wrap the request output stream in an output file, so the parquet writer can consume it + final OutputFile outputFile = new StreamOutputFile(new PositionTrackingOutputStream(new CountingOutputStream(outputStream))); + + final ConqueryParquetWriterBuilder conqueryParquetWriterBuilder = + new ConqueryParquetWriterBuilder(outputFile) + .setIdHeaders(idHeaders) + .setResultInfo(resultInfo) + .setPrintSettings(printSettings); + + try (final ParquetWriter parquetWriter = conqueryParquetWriterBuilder.build()) { + + /* + WORKAROUND: We need the conversion to SinglelineEntityResult here because a RecordConsumer only produces one line/record + even if multiple messages are started. + */ + Iterator resultIterator = results.flatMap(ParquetRenderer::convertToSingleLine).iterator(); + while (resultIterator.hasNext()) { + final EntityResult entityResult = resultIterator.next(); + + parquetWriter.write(entityResult); + } + } + } + + /** + * Converts a possible {@link MultilineEntityResult} to a stream of {@link SinglelineEntityResult}s. + * + * @param entityResult the result to convert. + * @return the stream of {@link SinglelineEntityResult}s + */ + private static Stream convertToSingleLine(EntityResult entityResult) { + if (entityResult instanceof SinglelineEntityResult) { + return Stream.of((SinglelineEntityResult) entityResult); + } + return entityResult.streamValues().map(line -> new SinglelineEntityResult(entityResult.getEntityId(), line)); + } + @RequiredArgsConstructor public static class StreamOutputFile implements OutputFile { @@ -35,7 +79,7 @@ public PositionOutputStream create(long blockSizeHint) throws IOException { } @Override - public PositionOutputStream createOrOverwrite(long blockSizeHint) throws IOException { + public PositionOutputStream createOrOverwrite(long blockSizeHint) { return outputStream; } @@ -53,10 +97,10 @@ public long defaultBlockSize() { @RequiredArgsConstructor public static class PositionTrackingOutputStream extends PositionOutputStream { - final private CountingOutputStream stream; + private final CountingOutputStream stream; @Override - public long getPos() throws IOException { + public long getPos() { return stream.getCount(); } @@ -66,51 +110,5 @@ public void write(int b) throws IOException { } } - public static void writeToStream( - OutputStream outputStream, - - List idHeaders, - List resultInfo, - PrintSettings printSettings, - Stream results) throws IOException { - - // Wrap the request output stream in an output file, so the parquet writer can consume it - final OutputFile outputFile = new StreamOutputFile( - new PositionTrackingOutputStream( - new CountingOutputStream(outputStream))); - - final ConqueryParquetWriterBuilder conqueryParquetWriterBuilder = new ConqueryParquetWriterBuilder(outputFile) - .setIdHeaders(idHeaders) - .setResultInfo(resultInfo) - .setPrintSettings(printSettings); - - try (final ParquetWriter parquetWriter = conqueryParquetWriterBuilder.build()) { - - /* - WORKAROUND: We need the conversion to SinglelineEntityResult here because a RecordConsumer only produces one line/record - even if multiple messages are started. - */ - Iterator resultIterator = results.flatMap(ParquetRenderer::convertToSingleLine).iterator(); - while (resultIterator.hasNext()) { - final EntityResult entityResult = resultIterator.next(); - - parquetWriter.write(entityResult); - } - } - } - - /** - * Converts a possible {@link MultilineEntityResult} to a stream of {@link SinglelineEntityResult}s. - * - * @param entityResult the result to convert. - * @return the stream of {@link SinglelineEntityResult}s - */ - private static Stream convertToSingleLine(EntityResult entityResult) { - if (entityResult instanceof SinglelineEntityResult) { - return Stream.of((SinglelineEntityResult) entityResult); - } - return entityResult.streamValues().map(line -> new SinglelineEntityResult(entityResult.getEntityId(), line)); - } - } diff --git a/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ResultParquetProcessor.java b/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ResultParquetProcessor.java index 6dfb0e61e0..33ce54324a 100644 --- a/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ResultParquetProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/io/result/parquet/ResultParquetProcessor.java @@ -59,8 +59,8 @@ public Response createResultFile(Subject subject, ManagedExecution exec, boolean final SingleTableResult singleTableResult = (SingleTableResult) exec; ParquetRenderer.writeToStream( output, - config.getIdColumns().getIdResultInfos(settings), - singleTableResult.getResultInfos(settings), + config.getIdColumns().getIdResultInfos(), + singleTableResult.getResultInfos(), settings, singleTableResult.streamResults(limit) ); diff --git a/backend/src/main/java/com/bakdata/conquery/mode/cluster/InternalMapperFactory.java b/backend/src/main/java/com/bakdata/conquery/mode/cluster/InternalMapperFactory.java index 9aa102eb54..e69775eddf 100644 --- a/backend/src/main/java/com/bakdata/conquery/mode/cluster/InternalMapperFactory.java +++ b/backend/src/main/java/com/bakdata/conquery/mode/cluster/InternalMapperFactory.java @@ -1,7 +1,5 @@ package com.bakdata.conquery.mode.cluster; -import jakarta.validation.Validator; - import com.bakdata.conquery.io.jackson.Jackson; import com.bakdata.conquery.io.jackson.MutableInjectableValues; import com.bakdata.conquery.io.jackson.View; @@ -12,6 +10,7 @@ import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationConfig; +import jakarta.validation.Validator; public record InternalMapperFactory(ConqueryConfig config, Validator validator) { @@ -31,6 +30,7 @@ public ObjectMapper createWorkerPersistenceMapper(ShardWorkers workers) { final ObjectMapper objectMapper = createInternalObjectMapper(View.Persistence.Shard.class); workers.injectInto(objectMapper); + config.injectInto(objectMapper); return objectMapper; } @@ -40,6 +40,7 @@ public ObjectMapper createNamespacePersistenceMapper(DatasetRegistry datasetR datasetRegistry.injectInto(objectMapper); + return objectMapper; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/common/Range.java b/backend/src/main/java/com/bakdata/conquery/models/common/Range.java index 49bac9bf77..c085c4aec2 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/common/Range.java +++ b/backend/src/main/java/com/bakdata/conquery/models/common/Range.java @@ -1,7 +1,9 @@ package com.bakdata.conquery.models.common; +import java.math.BigDecimal; import java.util.Optional; +import com.bakdata.conquery.models.config.FrontendConfig; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; @@ -10,7 +12,6 @@ import lombok.Getter; import lombok.NonNull; import lombok.With; -import lombok.experimental.Wither; @With @Getter @@ -20,30 +21,25 @@ public class Range implements IRange> { private final T min; private final T max; - public Range(T min, T max){ + public Range(T min, T max) { this.min = min; this.max = max; - if(!isOrdered()) { + if (!isOrdered()) { throw new IllegalArgumentException(String.format("min '%s' is not less than max '%s'", min, max)); } } - @Override - public String toString() { - if (isExactly()) { - return "[" + getMin() + "]"; - } - - if (isAtLeast()) { - return "[" + getMin() + ", +∞)"; - } - - if (isAtMost()) { - return "(-∞, " + getMax() + "]"; - } + @ValidationMethod(message = "If a range is not open in one direction, min needs to be less or equal to max") + @JsonIgnore + public final boolean isOrdered() { + return isOpen() || min.compareTo(max) <= 0; + } - return "[" + getMin() + ", " + getMax() + "]"; + @Override + @JsonIgnore + public boolean isOpen() { + return max == null || min == null; } public static > Range exactly(T exactly) { @@ -67,6 +63,23 @@ public static > Range all() { return new Range<>(null, null); } + @Override + public String toString() { + if (isExactly()) { + return "[" + getMin() + "]"; + } + + if (isAtLeast()) { + return "[" + getMin() + ", +∞)"; + } + + if (isAtMost()) { + return "(-∞, " + getMax() + "]"; + } + + return "[" + getMin() + ", " + getMax() + "]"; + } + @Override @JsonIgnore public boolean isExactly() { @@ -85,18 +98,6 @@ public boolean isAtMost() { return max != null && min == null; } - @Override - @JsonIgnore - public boolean isAll() { - return max == null && min == null; - } - - @Override - @JsonIgnore - public boolean isOpen() { - return max == null || min == null; - } - @Override public boolean contains(Range other) { if (other == null) { @@ -126,12 +127,24 @@ public boolean contains(Range other) { return contains(other.getMin()) && contains(other.getMax()); } - @ValidationMethod(message = "If a range is not open in one direction, min needs to be less or equal to max") + @Override @JsonIgnore - public final boolean isOrdered() { - return isOpen() || min.compareTo(max) <= 0; + public boolean isAll() { + return max == null && min == null; } + @Override + public boolean contains(T value) { + if (value == null) { + return false; + } + + if (getMin() != null && value.compareTo(getMin()) < 0) { + return false; + } + + return getMax() == null || value.compareTo(getMax()) <= 0; + } @Override public Range span(@NonNull Range other) { @@ -148,28 +161,15 @@ public Range span(@NonNull Range other) { return out; } - @Override - public boolean contains(T value) { - if(value == null) { - return false; - } - - if (getMin() != null && value.compareTo(getMin()) < 0) { - return false; - } - - return getMax() == null || value.compareTo(getMax()) <= 0; - } - public static class IntegerRange extends Range { public IntegerRange(Integer min, Integer max) { super(min, max); } - public static IntegerRange fromNumberRange(IRange orig){ - return new Range.IntegerRange( - Optional.ofNullable(orig.getMin()).map(Number::intValue).orElse(null), - Optional.ofNullable(orig.getMax()).map(Number::intValue).orElse(null)); + public static IntegerRange fromNumberRange(IRange orig) { + return new Range.IntegerRange(Optional.ofNullable(orig.getMin()).map(Number::intValue).orElse(null), + Optional.ofNullable(orig.getMax()).map(Number::intValue).orElse(null) + ); } @Override @@ -177,30 +177,30 @@ public boolean contains(Integer value) { return value != null && contains(value.intValue()); } - public boolean contains(Number value) { - return value != null && contains(value.intValue()); - } - public boolean contains(int value) { - if(getMin() != null && value < getMin()) { + if (getMin() != null && value < getMin()) { return false; } - if(getMax() != null && value > getMax()) { + if (getMax() != null && value > getMax()) { return false; } return true; } + + public boolean contains(Number value) { + return value != null && contains(value.intValue()); + } } public static class LongRange extends Range { - public LongRange (Long min, Long max) { + public LongRange(Long min, Long max) { super(min, max); } - public static LongRange fromNumberRange(IRange orig){ - return new Range.LongRange( - Optional.ofNullable(orig.getMin()).map(Number::longValue).orElse(null), - Optional.ofNullable(orig.getMax()).map(Number::longValue).orElse(null)); + public static LongRange fromNumberRange(IRange orig) { + return new Range.LongRange(Optional.ofNullable(orig.getMin()).map(Number::longValue).orElse(null), + Optional.ofNullable(orig.getMax()).map(Number::longValue).orElse(null) + ); } @Override @@ -208,19 +208,19 @@ public boolean contains(Long value) { return value != null && contains(value.longValue()); } - public boolean contains(Number value) { - return value != null && contains(value.longValue()); - } - public boolean contains(long value) { - if(getMin() != null && value < getMin()) { + if (getMin() != null && value < getMin()) { return false; } - if(getMax() != null && value > getMax()) { + if (getMax() != null && value > getMax()) { return false; } return true; } + + public boolean contains(Number value) { + return value != null && contains(value.longValue()); + } } public static class FloatRange extends Range { @@ -228,10 +228,10 @@ public FloatRange(Float min, Float max) { super(min, max); } - public static FloatRange fromNumberRange(IRange orig){ - return new Range.FloatRange( - Optional.ofNullable(orig.getMin()).map(Number::floatValue).orElse(null), - Optional.ofNullable(orig.getMax()).map(Number::floatValue).orElse(null)); + public static FloatRange fromNumberRange(IRange orig) { + return new Range.FloatRange(Optional.ofNullable(orig.getMin()).map(Number::floatValue).orElse(null), + Optional.ofNullable(orig.getMax()).map(Number::floatValue).orElse(null) + ); } @Override @@ -239,22 +239,22 @@ public boolean contains(Float value) { return value != null && contains(value.floatValue()); } - public boolean contains(Number value) { - return value != null && contains(value.floatValue()); - } - public boolean contains(float value) { - if(getMin() != null && value < getMin()) { + if (getMin() != null && value < getMin()) { return false; } - if(getMax() != null && value > getMax()) { + if (getMax() != null && value > getMax()) { return false; } - if(Float.isNaN(value)) { + if (Float.isNaN(value)) { return false; } return true; } + + public boolean contains(Number value) { + return value != null && contains(value.floatValue()); + } } public static class DoubleRange extends Range { @@ -262,10 +262,10 @@ public DoubleRange(Double min, Double max) { super(min, max); } - public static DoubleRange fromNumberRange(IRange orig){ - return new Range.DoubleRange( - Optional.ofNullable(orig.getMin()).map(Number::doubleValue).orElse(null), - Optional.ofNullable(orig.getMax()).map(Number::doubleValue).orElse(null)); + public static DoubleRange fromNumberRange(IRange orig) { + return new Range.DoubleRange(Optional.ofNullable(orig.getMin()).map(Number::doubleValue).orElse(null), + Optional.ofNullable(orig.getMax()).map(Number::doubleValue).orElse(null) + ); } @Override @@ -273,21 +273,42 @@ public boolean contains(Double value) { return value != null && contains(value.doubleValue()); } - public boolean contains(Number value) { - return value != null && contains(value.doubleValue()); - } - public boolean contains(double value) { - if(getMin() != null && value < getMin()) { + if (getMin() != null && value < getMin()) { return false; } - if(getMax() != null && value > getMax()) { + if (getMax() != null && value > getMax()) { return false; } - if(Double.isNaN(value)) { + if (Double.isNaN(value)) { return false; } return true; } + + public boolean contains(Number value) { + return value != null && contains(value.doubleValue()); + } } + + public static class MoneyRange extends Range { + public MoneyRange(BigDecimal min, BigDecimal max) { + super(min, max); + } + + public static MoneyRange fromNumberRange(IRange orig, FrontendConfig.CurrencyConfig currency) { + BigDecimal mappedMin = Optional.ofNullable(orig.getMin()) + .map(val -> new BigDecimal(val.longValue()).movePointLeft(currency.getDecimalScale())) + .orElse(null); + + BigDecimal mappedMax = Optional.ofNullable(orig.getMax()) + .map(val -> new BigDecimal(val.longValue()).movePointLeft(currency.getDecimalScale())) + .orElse(null); + + return new Range.MoneyRange(mappedMin, mappedMax); + } + + + } + } diff --git a/backend/src/main/java/com/bakdata/conquery/models/config/ExcelConfig.java b/backend/src/main/java/com/bakdata/conquery/models/config/ExcelConfig.java index 0aa040d8c3..bdf0cc42d4 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/config/ExcelConfig.java +++ b/backend/src/main/java/com/bakdata/conquery/models/config/ExcelConfig.java @@ -1,5 +1,11 @@ package com.bakdata.conquery.models.config; +import java.util.Collections; +import java.util.Map; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + import com.bakdata.conquery.models.query.PrintSettings; import com.google.common.collect.ImmutableMap; import lombok.AllArgsConstructor; @@ -12,15 +18,6 @@ import org.apache.poi.ss.usermodel.Font; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFDataFormat; -import org.apache.poi.xssf.usermodel.XSSFFont; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import java.util.Collections; -import java.util.Map; @Data public class ExcelConfig { @@ -33,7 +30,8 @@ public class ExcelConfig { private static final Map FALLBACK_STYLES = Map.of( BASIC_STYLE, new CellStyler(), - CURRENCY_STYLE_PREFIX + "EUR", new CellStyler().withDataFormatString("#,##0.00 €"), + // \u00A0 is the non breakable space + CURRENCY_STYLE_PREFIX + "EUR", new CellStyler().withDataFormatString("#,##0.00\u00A0€"), NUMERIC_STYLE, new CellStyler().withDataFormatString("#,##0.00"), INTEGER_STYLE, new CellStyler().withDataFormatString("#,##0") ); diff --git a/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java b/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java index 633ffbc9f4..5f2e713f22 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java +++ b/backend/src/main/java/com/bakdata/conquery/models/config/ExcelResultProvider.java @@ -13,8 +13,6 @@ import com.bakdata.conquery.io.result.ResultRender.ResultRendererProvider; import com.bakdata.conquery.io.result.excel.ResultExcelProcessor; import com.bakdata.conquery.models.execution.ManagedExecution; -import com.bakdata.conquery.models.i18n.I18n; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.SingleTableResult; import com.bakdata.conquery.resources.api.ResultExcelResource; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -73,13 +71,10 @@ public Collection generateResultURLs(ManagedExecution exec, UriBuil return Collections.emptyList(); } - - final PrintSettings printSettings = new PrintSettings(true, I18n.LOCALE.get(), exec.getNamespace(), exec.getConfig(), null, null); - // Save id column count to later check if xlsx dimensions are feasible - idColumnsCount = exec.getConfig().getIdColumns().getIdResultInfos(printSettings).size(); + idColumnsCount = exec.getConfig().getIdColumns().getIdResultInfos().size(); - final int columnCount = singleExecution.getResultInfos(printSettings).size() + idColumnsCount; + final int columnCount = singleExecution.getResultInfos().size() + idColumnsCount; final int maxColumnCount = SpreadsheetVersion.EXCEL2007.getMaxColumns(); if (columnCount > maxColumnCount) { diff --git a/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java b/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java index ebac0b4a46..c757481494 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java +++ b/backend/src/main/java/com/bakdata/conquery/models/config/IdColumnConfig.java @@ -15,7 +15,6 @@ import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.FixedLabelResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -123,20 +122,24 @@ public boolean isExactlyOnePseudo() { * @return */ @JsonIgnore - public List getIdResultInfos(PrintSettings printSettings) { + public List getIdResultInfos() { return ids.stream().filter(ColumnConfig::isPrint).map(col -> { - final Map labels = col.getLabel(); - // Get the label for the locale, - // fall back to any label if there is exactly one defined, - // then fall back to the field name. - final String label = Objects.requireNonNullElse(labels.getOrDefault( - printSettings.getLocale(), - // fall backs - labels.size() == 1 ? labels.values().stream().collect(MoreCollectors.onlyElement()) : col.getField() - ), col.getField()); //TODO we can now hook our anonymizers into this - return new FixedLabelResultInfo(label, label, ResultType.Primitive.STRING, Set.of(new SemanticType.IdT(col.getName())), printSettings, ResultPrinters.printerFor(ResultType.Primitive.STRING, printSettings)); + return new FixedLabelResultInfo(ResultType.Primitive.STRING, Set.of(new SemanticType.IdT(col.getName()))) { + @Override + public String userColumnName(PrintSettings printSettings) { + final Map labels = col.getLabel(); + // Get the label for the locale, + // fall back to any label if there is exactly one defined, + // then fall back to the field name. + return Objects.requireNonNullElse(labels.getOrDefault( + printSettings.getLocale(), + // fall backs + labels.size() == 1 ? labels.values().stream().collect(MoreCollectors.onlyElement()) : col.getField() + ), col.getField()); + } + }; }).collect(Collectors.toUnmodifiableList()); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/NumberFilter.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/NumberFilter.java index 97097425e7..37e250de19 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/NumberFilter.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/filters/specific/NumberFilter.java @@ -10,6 +10,7 @@ import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.datasets.concepts.filters.Filter; import com.bakdata.conquery.models.datasets.concepts.filters.SingleColumnFilter; +import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.exceptions.ConceptConfigurationException; import com.bakdata.conquery.models.query.filter.event.number.DecimalFilterNode; import com.bakdata.conquery.models.query.filter.event.number.IntegerFilterNode; @@ -18,6 +19,11 @@ import com.bakdata.conquery.models.query.queryplan.filter.FilterNode; import com.bakdata.conquery.sql.conversion.model.filter.FilterConverter; import com.bakdata.conquery.sql.conversion.model.filter.NumberFilterConverter; +import com.fasterxml.jackson.annotation.JacksonInject; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.OptBoolean; +import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -31,6 +37,12 @@ @CPSType(id = "NUMBER", base = Filter.class) public class NumberFilter> extends SingleColumnFilter { + @JsonIgnore + @JacksonInject(useInput = OptBoolean.FALSE) + @NotNull + @EqualsAndHashCode.Exclude + private ConqueryConfig config; + @Override public void configureFrontend(FrontendFilterConfiguration.Top f, ConqueryConfig conqueryConfig) throws ConceptConfigurationException { final String type = switch (getColumn().getType()) { @@ -43,19 +55,32 @@ public void configureFrontend(FrontendFilterConfiguration.Top f, ConqueryConfig f.setType(type); } - @Override public FilterNode createFilterNode(RANGE value) { + final IRange range = readFilterValue(value, getColumn().getType(), config); return switch (getColumn().getType()) { - case MONEY -> new MoneyFilterNode(getColumn(), (Range.LongRange) value); - case INTEGER -> new IntegerFilterNode(getColumn(), (Range.LongRange) value); - case DECIMAL -> new DecimalFilterNode(getColumn(), ((Range) value)); - case REAL -> new RealFilterNode(getColumn(), Range.DoubleRange.fromNumberRange(value)); + case MONEY -> new MoneyFilterNode(getColumn(), (Range.MoneyRange) range); + case INTEGER -> new IntegerFilterNode(getColumn(), (Range.LongRange) range); + case DECIMAL -> new DecimalFilterNode(getColumn(), (Range) range); + case REAL -> new RealFilterNode(getColumn(), (Range.DoubleRange) range); default -> throw new IllegalStateException(String.format("Column type %s may not be used (Assignment should not have been possible)", getColumn())); }; } + /** + * This method only exists because we messed up and never implemented a DECIMAL_RANGE, otherwise it could be embedded in the FilterValues themselves. + */ + public static IRange readFilterValue(IRange value, @NotNull MajorTypeId type, @NotNull ConqueryConfig config) { + return switch (type) { + case MONEY -> Range.MoneyRange.fromNumberRange(value, config.getFrontend().getCurrency()); + case INTEGER -> (Range.LongRange) value; + case DECIMAL -> ((Range) value); + case REAL -> Range.DoubleRange.fromNumberRange(value); + default -> throw new IllegalStateException(String.format("Column type %s may not be used (Assignment should not have been possible)", type)); + }; + } + @Override public FilterConverter, RANGE> createConverter() { return new NumberFilterConverter<>(); diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java index c7c5b026d7..465581e2de 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/Select.java @@ -18,7 +18,8 @@ import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; import com.fasterxml.jackson.annotation.JsonBackReference; @@ -87,8 +88,8 @@ public String getColumnName() { + getLabel(); } - public SelectResultInfo getResultInfo(CQConcept cqConcept, PrintSettings settings) { - return new SelectResultInfo(this, cqConcept, Collections.emptySet(), settings); + public SelectResultInfo getResultInfo(CQConcept cqConcept) { + return new SelectResultInfo(this, cqConcept, Collections.emptySet()); } @@ -128,7 +129,7 @@ public boolean isEventDateSelect() { return false; } - public ResultPrinters.Printer createPrinter(PrintSettings printSettings) { - return ResultPrinters.printerFor(getResultType(), printSettings); + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + return printerFactory.printerFor(getResultType(), printSettings); } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java index 47203e23a1..5cf893887f 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/concept/ConceptColumnSelect.java @@ -13,7 +13,9 @@ import com.bakdata.conquery.models.query.queryplan.aggregators.specific.value.ConceptElementsAggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.value.ConceptValuesAggregator; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.common.ConceptIdPrinter; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import com.bakdata.conquery.sql.conversion.model.select.ConceptColumnSelectConverter; @@ -44,21 +46,21 @@ public Aggregator createAggregator() { } @Override - public ResultPrinters.Printer createPrinter(PrintSettings printSettings) { + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { if (isAsIds()) { - return new ResultPrinters.ListPrinter(new ResultPrinters.ConceptIdPrinter(getHolder().findConcept(), printSettings), printSettings); + return printerFactory.getListPrinter(new ConceptIdPrinter(getHolder().findConcept(), printSettings), printSettings); } - return new ResultPrinters.ListPrinter(new ResultPrinters.StringPrinter(), printSettings); + return printerFactory.getListPrinter(printerFactory.getStringPrinter(printSettings), printSettings); } @Override - public SelectResultInfo getResultInfo(CQConcept cqConcept, PrintSettings settings) { - if (!isAsIds()) { - return new SelectResultInfo(this, cqConcept, Collections.emptySet(), settings); + public SelectResultInfo getResultInfo(CQConcept cqConcept) { + if (isAsIds()) { + return new SelectResultInfo(this, cqConcept, Set.of(new SemanticType.ConceptColumnT(cqConcept.getConcept()))); } + return new SelectResultInfo(this, cqConcept, Collections.emptySet()); - return new SelectResultInfo(this, cqConcept, Set.of(new SemanticType.ConceptColumnT(cqConcept.getConcept())), settings); } @JsonIgnore diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java index 3a70cfc5cc..5f1ad1b075 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/DistinctSelect.java @@ -9,7 +9,9 @@ import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.queryplan.aggregators.specific.value.AllValuesAggregator; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.common.MappedPrinter; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.conversion.model.select.DistinctSelectConverter; import com.bakdata.conquery.sql.conversion.model.select.SelectConverter; @@ -40,11 +42,11 @@ public SelectConverter createConverter() { } @Override - public ResultPrinters.Printer createPrinter(PrintSettings printSettings) { + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { if(getMapping() == null){ - return super.createPrinter(printSettings); + return super.createPrinter(printerFactory, printSettings); } - return new ResultPrinters.ListPrinter(new ResultPrinters.MappedPrinter(getMapping()), printSettings); + return printerFactory.getListPrinter(new MappedPrinter(getMapping()), printSettings); } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java index a8a5e16ff0..98b0c82f81 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/SingleColumnSelect.java @@ -11,7 +11,6 @@ import com.bakdata.conquery.models.datasets.concepts.Connector; import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.events.MajorTypeId; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; import com.bakdata.conquery.models.types.SemanticType; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -50,13 +49,13 @@ public EnumSet getAcceptedColumnTypes() { } @Override - public SelectResultInfo getResultInfo(CQConcept cqConcept, PrintSettings settings) { + public SelectResultInfo getResultInfo(CQConcept cqConcept) { if(categorical){ - return new SelectResultInfo(this, cqConcept, Set.of(new SemanticType.CategoricalT()), settings); + return new SelectResultInfo(this, cqConcept, Set.of(new SemanticType.CategoricalT())); } - return new SelectResultInfo(this, cqConcept, Collections.emptySet(), settings); + return new SelectResultInfo(this, cqConcept, Collections.emptySet()); } @Nullable diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountOccurencesSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountOccurencesSelect.java deleted file mode 100644 index c06d8cf943..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/CountOccurencesSelect.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.bakdata.conquery.models.datasets.concepts.select.connector.specific; - -import java.util.EnumSet; - -import com.bakdata.conquery.io.cps.CPSType; -import com.bakdata.conquery.io.jackson.serializer.NsIdRef; -import com.bakdata.conquery.models.datasets.Column; -import com.bakdata.conquery.models.datasets.concepts.select.Select; -import com.bakdata.conquery.models.datasets.concepts.select.connector.SingleColumnSelect; -import com.bakdata.conquery.models.events.MajorTypeId; -import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; -import com.bakdata.conquery.models.query.queryplan.aggregators.specific.MultiSelectAggregator; -import com.bakdata.conquery.models.query.queryplan.aggregators.specific.SelectAggregator; -import com.bakdata.conquery.models.types.ResultType; -import com.fasterxml.jackson.annotation.JsonCreator; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; - -//TODO delete? -@CPSType(id = "COUNT_OCCURENCES", base = Select.class) -public class CountOccurencesSelect extends SingleColumnSelect { - - @Override - public EnumSet getAcceptedColumnTypes() { - return EnumSet.of(MajorTypeId.STRING); - } - - @Getter - @Setter - @NotNull - private String[] selection; - - @JsonCreator - public CountOccurencesSelect(@NsIdRef Column column, String[] selection) { - super(column); - this.selection = selection; - } - - @Override - public Aggregator createAggregator() { - if (selection.length == 1) { - return new SelectAggregator(getColumn(), selection[0]); - } - - return new MultiSelectAggregator(getColumn(), selection); - } - - @Override - public ResultType getResultType() { - return ResultType.Primitive.INTEGER; - } -} diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java index 4d9ea4faa6..af5d6ebe2d 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/select/connector/specific/MappableSingleColumnSelect.java @@ -13,7 +13,9 @@ import com.bakdata.conquery.models.index.InternToExternMapper; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.common.MappedPrinter; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import jakarta.validation.Valid; @@ -38,27 +40,27 @@ public MappableSingleColumnSelect(Column column, @Nullable InternToExternMapper } @Override - public ResultPrinters.Printer createPrinter(PrintSettings printSettings) { + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { if (mapping == null) { - return super.createPrinter(printSettings); + return super.createPrinter(printerFactory, printSettings); } - return new ResultPrinters.MappedPrinter(getMapping()); + return new MappedPrinter(getMapping()); } @Override - public SelectResultInfo getResultInfo(CQConcept cqConcept, PrintSettings settings) { + public SelectResultInfo getResultInfo(CQConcept cqConcept) { if (!isCategorical()) { - return new SelectResultInfo(this, cqConcept, Collections.emptySet(), settings); + return new SelectResultInfo(this, cqConcept, Collections.emptySet()); } - return new SelectResultInfo(this, cqConcept, Set.of(new SemanticType.CategoricalT()), settings); + return new SelectResultInfo(this, cqConcept, Set.of(new SemanticType.CategoricalT())); } @Override public ResultType getResultType() { - if(mapping == null){ + if (mapping == null) { return ResultType.resolveResultType(getColumn().getType()); } return ResultType.Primitive.STRING; diff --git a/backend/src/main/java/com/bakdata/conquery/models/events/Bucket.java b/backend/src/main/java/com/bakdata/conquery/models/events/Bucket.java index 530aa94187..0972141c42 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/events/Bucket.java +++ b/backend/src/main/java/com/bakdata/conquery/models/events/Bucket.java @@ -162,7 +162,7 @@ public BigDecimal getDecimal(int event, @NotNull Column column) { return ((DecimalStore) getStore(column)).getDecimal(event); } - public long getMoney(int event, @NotNull Column column) { + public BigDecimal getMoney(int event, @NotNull Column column) { return ((MoneyStore) getStore(column)).getMoney(event); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/events/EmptyBucket.java b/backend/src/main/java/com/bakdata/conquery/models/events/EmptyBucket.java index 5d1551cb8d..418f5f74ce 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/events/EmptyBucket.java +++ b/backend/src/main/java/com/bakdata/conquery/models/events/EmptyBucket.java @@ -73,7 +73,7 @@ public BigDecimal getDecimal(int event, Column column) { } @Override - public long getMoney(int event, Column column) { + public BigDecimal getMoney(int event, Column column) { throw new IllegalStateException("Bucket for ALL_IDS_TABLE may not be evaluated."); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/events/EmptyStore.java b/backend/src/main/java/com/bakdata/conquery/models/events/EmptyStore.java index 7201ae0ac9..aa32018ac3 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/events/EmptyStore.java +++ b/backend/src/main/java/com/bakdata/conquery/models/events/EmptyStore.java @@ -114,12 +114,12 @@ public void setInteger(int event, long value) { } @Override - public long getMoney(int event) { - return 0; + public BigDecimal getMoney(int event) { + return BigDecimal.ZERO; } @Override - public void setMoney(int event, long money) { + public void setMoney(int event, BigDecimal money) { } diff --git a/backend/src/main/java/com/bakdata/conquery/models/events/stores/root/MoneyStore.java b/backend/src/main/java/com/bakdata/conquery/models/events/stores/root/MoneyStore.java index 96c048f281..c520e21e5e 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/events/stores/root/MoneyStore.java +++ b/backend/src/main/java/com/bakdata/conquery/models/events/stores/root/MoneyStore.java @@ -1,6 +1,8 @@ package com.bakdata.conquery.models.events.stores.root; +import java.math.BigDecimal; + import com.bakdata.conquery.models.events.MajorTypeId; /** @@ -9,8 +11,8 @@ */ public interface MoneyStore extends ColumnStore { - long getMoney(int event); - void setMoney(int event, long money); + BigDecimal getMoney(int event); + void setMoney(int event, BigDecimal money); @Override default Object createScriptValue(int event) { diff --git a/backend/src/main/java/com/bakdata/conquery/models/events/stores/specific/MoneyIntStore.java b/backend/src/main/java/com/bakdata/conquery/models/events/stores/specific/MoneyIntStore.java index c66faaae0e..1784c7f7c5 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/events/stores/specific/MoneyIntStore.java +++ b/backend/src/main/java/com/bakdata/conquery/models/events/stores/specific/MoneyIntStore.java @@ -1,26 +1,49 @@ package com.bakdata.conquery.models.events.stores.specific; +import java.math.BigDecimal; + import com.bakdata.conquery.io.cps.CPSType; +import com.bakdata.conquery.io.jackson.Initializing; +import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.events.Bucket; import com.bakdata.conquery.models.events.stores.root.ColumnStore; import com.bakdata.conquery.models.events.stores.root.IntegerStore; import com.bakdata.conquery.models.events.stores.root.MoneyStore; +import com.fasterxml.jackson.annotation.JacksonInject; import com.fasterxml.jackson.annotation.JsonCreator; -import lombok.Getter; -import lombok.Setter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.OptBoolean; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import lombok.ToString; +import lombok.experimental.Accessors; @CPSType(base = ColumnStore.class, id = "MONEY_VARINT") -@Getter -@Setter +@Data @ToString(of = "numberType") -public class MoneyIntStore implements MoneyStore { +@NoArgsConstructor(onConstructor_ = {@JsonCreator}) +@JsonDeserialize(converter = MoneyIntStore.MoneyIntStoreInitializer.class) +public class MoneyIntStore implements MoneyStore, Initializing { + + @JsonIgnore + @JacksonInject(useInput = OptBoolean.FALSE) + @EqualsAndHashCode.Exclude + @Accessors(fluent = true) + private ConqueryConfig config; + + private IntegerStore numberType; - protected IntegerStore numberType; + @JsonProperty(required = false) + private int decimalShift = Integer.MIN_VALUE; - @JsonCreator - public MoneyIntStore(IntegerStore numberType) { - this.numberType = numberType; + + public MoneyIntStore(IntegerStore store, int decimalShift){ + this(); + this.numberType = store; + this.decimalShift = decimalShift; } @Override @@ -30,17 +53,17 @@ public int getLines() { @Override public MoneyIntStore createDescription() { - return new MoneyIntStore(numberType.createDescription()); + return new MoneyIntStore(numberType.createDescription(), getDecimalShift()); } @Override public MoneyIntStore select(int[] starts, int[] length) { - return new MoneyIntStore(numberType.select(starts, length)); + return new MoneyIntStore(numberType.select(starts, length), getDecimalShift()); } @Override - public long getMoney(int event) { - return numberType.getInteger(event); + public BigDecimal getMoney(int event) { + return BigDecimal.valueOf(numberType.getInteger(event)).movePointLeft(decimalShift); } @Override @@ -49,8 +72,8 @@ public long estimateEventBits() { } @Override - public void setMoney(int event, long value) { - numberType.setInteger(event, value); + public void setMoney(int event, BigDecimal value) { + numberType.setInteger(event, value.movePointRight(decimalShift).longValue()); } @Override @@ -66,4 +89,16 @@ public final boolean has(int event) { public void setParent(Bucket bucket) { // not used } + + @Override + public void init() { + if (decimalShift != Integer.MIN_VALUE){ + return; + } + + decimalShift = config.getFrontend().getCurrency().getDecimalScale(); + } + + public static class MoneyIntStoreInitializer extends Initializing.Converter {} + } diff --git a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/AbsoluteFormQuery.java b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/AbsoluteFormQuery.java index 264d3d1a4c..4a678ef4eb 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/AbsoluteFormQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/AbsoluteFormQuery.java @@ -17,7 +17,6 @@ import com.bakdata.conquery.models.forms.util.DateContext; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -43,7 +42,7 @@ public class AbsoluteFormQuery extends Query { public static final int TIME_INDEX = 2; /** - * see {@linkplain this#getResultInfos(PrintSettings)}. + * see {@linkplain #getResultInfos()}. */ public static final int FEATURES_OFFSET = 3; @@ -85,13 +84,13 @@ public AbsoluteFormQueryPlan createQueryPlan(QueryPlanContext context) { } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { final List resultInfos = new ArrayList<>(); - resultInfos.add(ResultHeaders.formResolutionInfo(printSettings)); - resultInfos.add(ResultHeaders.formContextInfo(printSettings)); - resultInfos.add(ResultHeaders.formDateRangeInfo(printSettings)); - resultInfos.addAll(features.getResultInfos(printSettings)); + resultInfos.add(ResultHeaders.formResolutionInfo()); + resultInfos.add(ResultHeaders.formContextInfo()); + resultInfos.add(ResultHeaders.formDateRangeInfo()); + resultInfos.addAll(features.getResultInfos()); return resultInfos; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/EntityDateQuery.java b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/EntityDateQuery.java index 68c6dce565..9b74f0830d 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/EntityDateQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/EntityDateQuery.java @@ -16,7 +16,6 @@ import com.bakdata.conquery.models.common.daterange.CDateRange; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -89,13 +88,13 @@ public void resolve(QueryResolveContext context) { } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { List resultInfos = new ArrayList<>(); - resultInfos.add(ResultHeaders.formResolutionInfo(printSettings)); - resultInfos.add(ResultHeaders.formContextInfo(printSettings)); - resultInfos.add(ResultHeaders.formDateRangeInfo(printSettings)); + resultInfos.add(ResultHeaders.formResolutionInfo()); + resultInfos.add(ResultHeaders.formContextInfo()); + resultInfos.add(ResultHeaders.formDateRangeInfo()); - resultInfos.addAll(features.getResultInfos(printSettings)); + resultInfos.addAll(features.getResultInfos()); return resultInfos; diff --git a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/ManagedInternalForm.java b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/ManagedInternalForm.java index 78c358701d..049ec237fd 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/ManagedInternalForm.java +++ b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/ManagedInternalForm.java @@ -23,7 +23,6 @@ import com.bakdata.conquery.models.query.ColumnDescriptor; import com.bakdata.conquery.models.query.ExecutionManager; import com.bakdata.conquery.models.query.ManagedQuery; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryResolveContext; import com.bakdata.conquery.models.query.SingleTableResult; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; @@ -136,11 +135,11 @@ public void cancel() { @Override @JsonIgnore - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { if (subQueries.size() != 1) { throw new UnsupportedOperationException("Cannot gather result info when multiple tables are generated"); } - return subQueries.values().iterator().next().getResultInfos(printSettings); + return subQueries.values().iterator().next().getResultInfos(); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java index 6b912d0596..2668aa332a 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/models/forms/managed/RelativeFormQuery.java @@ -16,7 +16,6 @@ import com.bakdata.conquery.models.forms.util.CalendarUnit; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.DateAggregationMode; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.QueryPlanContext; import com.bakdata.conquery.models.query.QueryResolveContext; @@ -74,17 +73,17 @@ public void collectRequiredQueries(Set requiredQueries) { } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { List resultInfos = new ArrayList<>(); - resultInfos.add(ResultHeaders.formResolutionInfo(printSettings)); - resultInfos.add(ResultHeaders.formContextInfo(printSettings)); - resultInfos.add(ResultHeaders.formEventDateInfo(printSettings)); - resultInfos.add(ResultHeaders.formDateRangeInfo(printSettings)); + resultInfos.add(ResultHeaders.formResolutionInfo()); + resultInfos.add(ResultHeaders.formContextInfo()); + resultInfos.add(ResultHeaders.formEventDateInfo()); + resultInfos.add(ResultHeaders.formDateRangeInfo()); - final List featureInfos = features.getResultInfos(printSettings); + final List featureInfos = features.getResultInfos(); - resultInfos.add(ResultHeaders.formObservationScopeInfo(printSettings)); + resultInfos.add(ResultHeaders.formObservationScopeInfo()); resultInfos.addAll(featureInfos); diff --git a/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/MoneyParser.java b/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/MoneyParser.java index 3d8049b4d0..31e6675686 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/MoneyParser.java +++ b/backend/src/main/java/com/bakdata/conquery/models/preproc/parser/specific/MoneyParser.java @@ -3,7 +3,6 @@ import java.math.BigDecimal; import com.bakdata.conquery.models.config.ConqueryConfig; -import com.bakdata.conquery.models.config.ParserConfig; import com.bakdata.conquery.models.events.stores.root.IntegerStore; import com.bakdata.conquery.models.events.stores.root.MoneyStore; import com.bakdata.conquery.models.events.stores.specific.MoneyIntStore; @@ -11,62 +10,58 @@ import com.bakdata.conquery.models.preproc.parser.ColumnValues; import com.bakdata.conquery.models.preproc.parser.Parser; import com.bakdata.conquery.util.NumberParsing; -import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.Getter; import lombok.ToString; @ToString(callSuper = true) -public class MoneyParser extends Parser { +public class MoneyParser extends Parser { - private long maxValue = Long.MIN_VALUE; - private long minValue = Long.MAX_VALUE; - - @JsonIgnore - private final BigDecimal moneyFactor; + private final int defaultFractionDigits; + private BigDecimal maxValue = null; + private BigDecimal minValue = null; public MoneyParser(ConqueryConfig config) { super(config); - moneyFactor = BigDecimal.valueOf(10).pow(config.getPreprocessor().getParsers().getCurrency().getDefaultFractionDigits()); + defaultFractionDigits = config.getPreprocessor().getParsers().getCurrency().getDefaultFractionDigits(); } @Override - protected Long parseValue(String value) throws ParsingException { - return NumberParsing - .parseMoney(value) - .multiply(moneyFactor) - .longValueExact(); + protected BigDecimal parseValue(String value) throws ParsingException { + return NumberParsing.parseMoney(value); } @Override - protected void registerValue(Long v) { - if (v > maxValue) { + protected void registerValue(BigDecimal v) { + if (maxValue == null){ maxValue = v; } - if (v < minValue) { + if(minValue == null){ minValue = v; } + + maxValue = maxValue.max(v); + minValue = minValue.min(v); } @Override protected MoneyStore decideType() { IntegerParser subParser = new IntegerParser(getConfig()); - subParser.registerValue(maxValue); - subParser.registerValue(minValue); + subParser.registerValue(maxValue.movePointRight(defaultFractionDigits).longValue()); + subParser.registerValue(minValue.movePointRight(defaultFractionDigits).longValue()); subParser.setLines(getLines()); subParser.setNullLines(getNullLines()); IntegerStore subDecision = subParser.findBestType(); - return new MoneyIntStore(subDecision); + return new MoneyIntStore(subDecision, defaultFractionDigits); } @Override - public void setValue(MoneyStore store, int event, Long value) { + public void setValue(MoneyStore store, int event, BigDecimal value) { store.setMoney(event, value); } @Override public ColumnValues createColumnValues() { - return new LongColumnValues(); + return new ListColumnValues(); } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/ManagedQuery.java b/backend/src/main/java/com/bakdata/conquery/models/query/ManagedQuery.java index 70896956f0..dc14fff906 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/ManagedQuery.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/ManagedQuery.java @@ -51,8 +51,6 @@ public class ManagedQuery extends ManagedExecution implements SingleTableResult, */ private Long lastResultCount; - @JsonIgnore - private transient List columnDescriptions; public ManagedQuery(Query query, User owner, Dataset submittedDataset, MetaStorage storage, DatasetRegistry datasetRegistry) { @@ -112,15 +110,12 @@ public void setStatusBase(@NonNull Subject subject, @NonNull ExecutionStatus sta @Override protected void setAdditionalFieldsForStatusWithColumnDescription(Subject subject, FullExecutionStatus status, Namespace namespace) { - if (columnDescriptions == null) { - columnDescriptions = generateColumnDescriptions(isInitialized(), getConfig()); - } - status.setColumnDescriptions(columnDescriptions); + status.setColumnDescriptions(generateColumnDescriptions(isInitialized(), getConfig())); } @JsonIgnore - public List getResultInfos(PrintSettings printSettings) { - return query.getResultInfos(printSettings); + public List getResultInfos() { + return query.getResultInfos(); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/SingleTableResult.java b/backend/src/main/java/com/bakdata/conquery/models/query/SingleTableResult.java index 2823c5b6e0..0b9f33faa8 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/SingleTableResult.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/SingleTableResult.java @@ -20,28 +20,28 @@ public interface SingleTableResult { default List generateColumnDescriptions(boolean isInitialized, ConqueryConfig config) { Preconditions.checkArgument(isInitialized, "The execution must have been initialized first"); - List columnDescriptions = new ArrayList<>(); + final List columnDescriptions = new ArrayList<>(); final Locale locale = I18n.LOCALE.get(); + // The printer is never used to generate results. But downstream code might touch them + final PrintSettings settings = new PrintSettings(true, locale, getNamespace(), config, null, null); - PrintSettings settings = new PrintSettings(true, locale, getNamespace(), config, null, null); - - UniqueNamer uniqNamer = new UniqueNamer(settings); + final UniqueNamer uniqNamer = new UniqueNamer(settings); // First add the id columns to the descriptor list. The are the first columns - for (ResultInfo header : config.getIdColumns().getIdResultInfos(settings)) { + for (ResultInfo header : config.getIdColumns().getIdResultInfos()) { final ColumnDescriptor descriptor = - new ColumnDescriptor(uniqNamer.getUniqueName(header), null, null, ResultType.Primitive.STRING.typeInfo(), header.getSemantics()); + new ColumnDescriptor(uniqNamer.getUniqueName(header, settings), null, null, ResultType.Primitive.STRING.typeInfo(), header.getSemantics()); columnDescriptions.add(descriptor); } final UniqueNamer collector = new UniqueNamer(settings); - getResultInfos(settings).forEach(info -> columnDescriptions.add(info.asColumnDescriptor(collector))); + getResultInfos().forEach(info -> columnDescriptions.add(info.asColumnDescriptor(collector, settings))); return columnDescriptions; } @JsonIgnore - List getResultInfos(PrintSettings printSettings); + List getResultInfos(); /** * @param limit Optionally limits how many lines are emitted. diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/filter/event/number/MoneyFilterNode.java b/backend/src/main/java/com/bakdata/conquery/models/query/filter/event/number/MoneyFilterNode.java index 9d1d8993d8..b6cbc41351 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/filter/event/number/MoneyFilterNode.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/filter/event/number/MoneyFilterNode.java @@ -6,9 +6,9 @@ import lombok.ToString; @ToString(callSuper = true) -public class MoneyFilterNode extends NumberFilterNode { +public class MoneyFilterNode extends NumberFilterNode { - public MoneyFilterNode(Column column, Range.LongRange filterValue) { + public MoneyFilterNode(Column column, Range.MoneyRange filterValue) { super(column, filterValue); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/preview/EntityPreviewExecution.java b/backend/src/main/java/com/bakdata/conquery/models/query/preview/EntityPreviewExecution.java index 59916a9ea6..45d4db741b 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/preview/EntityPreviewExecution.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/preview/EntityPreviewExecution.java @@ -1,6 +1,5 @@ package com.bakdata.conquery.models.query.preview; -import java.math.BigDecimal; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; @@ -35,18 +34,15 @@ import com.bakdata.conquery.models.query.SingleTableResult; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.JsonResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.query.results.MultilineEntityResult; -import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import com.bakdata.conquery.models.worker.DatasetRegistry; import com.bakdata.conquery.models.worker.Namespace; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.databind.node.BooleanNode; -import com.fasterxml.jackson.databind.node.DecimalNode; -import com.fasterxml.jackson.databind.node.IntNode; -import com.fasterxml.jackson.databind.node.TextNode; import com.google.common.collect.MoreCollectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -69,147 +65,6 @@ public EntityPreviewExecution(EntityPreviewForm entityPreviewQuery, User user, D super(entityPreviewQuery, user, submittedDataset, storage, datasetRegistry); } - /** - * Query contains both YEARS and QUARTERS lines: Group them. - */ - private static Map> getQuarterLines(EntityResult entityResult) { - final Map> quarterLines = new HashMap<>(); - - for (Object[] line : entityResult.listResultLines()) { - if (Resolution.valueOf((String) line[AbsoluteFormQuery.RESOLUTION_INDEX]) != Resolution.QUARTERS) { - continue; - } - - // Since we know the dates are always aligned we need to only respect their starts. - final LocalDate date = CDate.toLocalDate(((List) line[AbsoluteFormQuery.TIME_INDEX]).get(0)); - - final int year = date.getYear(); - final int quarter = QuarterUtils.getQuarter(date); - - quarterLines.computeIfAbsent(year, (ignored) -> new HashMap<>(4)).put(quarter, line); - } - - return quarterLines; - } - - /** - * Query contains both YEARS and QUARTERS lines: Group them. - */ - private static Map getYearLines(EntityResult entityResult) { - - final Map yearLines = new HashMap<>(); - - for (Object[] line : entityResult.listResultLines()) { - - if (Resolution.valueOf((String) line[AbsoluteFormQuery.RESOLUTION_INDEX]) != Resolution.YEARS) { - continue; - } - - // Since we know the dates are always aligned we need to only respect their starts. - final LocalDate date = CDate.toLocalDate(((List) line[AbsoluteFormQuery.TIME_INDEX]).get(0)); - - final int year = date.getYear(); - - yearLines.put(year, line); - } - - return yearLines; - } - - /** - * Creates a transformer printing lines, transformed into a Map of label->value. - * Null values are omitted. - */ - private static Function> createLineToMapTransformer(List resultInfos, Map select2desc, PrintSettings printSettings) { - - - final int size = resultInfos.size(); - final String[] columnNames = new String[size]; - - //TODO pull renderValue logic into outer loop, only use array as lookup - - for (int index = 0; index < size; index++) { - final ResultInfo resultInfo = resultInfos.get(index); - - if (resultInfo instanceof SelectResultInfo selectResultInfo) { - columnNames[index] = select2desc.get(selectResultInfo.getSelect().getId()).label(); - } - } - - return line -> { - final Map out = new HashMap<>(size); - - for (int column = 0; column < size; column++) { - final String columnName = columnNames[column]; - - if (columnName == null) { - continue; - } - - - final Object value = renderValue(line[column], resultInfos.get(column).getType(), printSettings); - - if (value == null) { - continue; - } - - out.put(columnName, value); - } - - return out; - }; - } - - /** - * Instead of outputting only String values, render to Json equivalents - */ - private static Object renderValue(Object value, ResultType type, PrintSettings printSettings) { - if (value == null) { - return null; - } - - if (type instanceof ResultType.ListT listT) { - return ((List) value).stream().map(entry -> renderValue(entry, listT.getElementType(), printSettings)).collect(Collectors.toList()); - } - - return switch (((ResultType.Primitive) type)) { - case BOOLEAN -> BooleanNode.valueOf((Boolean) value); - case INTEGER -> new IntNode((Integer) value); - case NUMERIC -> DecimalNode.valueOf((BigDecimal) value); - case DATE -> new TextNode(new ResultPrinters.DatePrinter(printSettings).print(value)); //TODO bind printers in outer loop - case DATE_RANGE -> new TextNode(new ResultPrinters.DateRangePrinter(printSettings).print(value)); //TODO bind printers in outer loop - case STRING -> new TextNode(value.toString()); //TODO mapping - case MONEY -> ResultPrinters.readMoney(printSettings, ((Number) value)); - }; - } - - /** - * For the selects in result infos, build ColumnDescriptors using definitions (label and description) from PreviewConfig. - */ - private static List createChronoColumnDescriptors(SingleTableResult query, Map select2desc, PrintSettings printSettings) { - - final List columnDescriptions = new ArrayList<>(); - - for (ResultInfo info : query.getResultInfos(printSettings)) { - if (info instanceof SelectResultInfo selectResultInfo) { - final PreviewConfig.InfoCardSelect additionalInfo = select2desc.get(selectResultInfo.getSelect().getId()); - - // We build these by hand because they are labeled and described by config. - final ColumnDescriptor descriptor = new ColumnDescriptor( - additionalInfo.label(), - additionalInfo.label(), - (additionalInfo.description() != null) ? additionalInfo.description() : selectResultInfo.getDescription(),// both might be null - info.getType().typeInfo(), - info.getSemantics() - ); - columnDescriptions.add(descriptor); - } - } - - - return columnDescriptions; - } - @Override public boolean isSystem() { // This Form should NEVER be started manually. Nor persisted @@ -237,19 +92,27 @@ public FullExecutionStatus buildStatusFull(Subject subject, Namespace namespace) status.setQuery(getValuesQuery().getQuery()); + JsonResultPrinters printers = new JsonResultPrinters(); + final PrintSettings infoSettings = new PrintSettings(true, I18n.LOCALE.get(), getNamespace(), getConfig(), null, previewConfig::resolveSelectLabel); + status.setInfos(transformQueryResultToInfos(getInfoCardExecution(), infoSettings, printers)); - status.setInfos(transformQueryResultToInfos(getInfoCardExecution(), new PrintSettings(true, I18n.LOCALE.get(), getNamespace(), getConfig(), null, previewConfig::resolveSelectLabel))); - - status.setTimeStratifiedInfos(toChronoInfos(previewConfig, getSubQueries(), new PrintSettings(false, I18n.LOCALE.get(), getNamespace(), getConfig(), null, previewConfig::resolveSelectLabel))); + final PrintSettings stratifiedSettings = new PrintSettings(false, I18n.LOCALE.get(), getNamespace(), getConfig(), null, previewConfig::resolveSelectLabel); + status.setTimeStratifiedInfos(toChronoInfos(previewConfig, getSubQueries(), stratifiedSettings, printers)); return status; } + @JsonIgnore + private ManagedQuery getValuesQuery() { + return getSubQueries().get(EntityPreviewForm.VALUES_QUERY_NAME); + } + /** * Takes a ManagedQuery, and transforms its result into a List of {@link EntityPreviewStatus.Info}. * The format of the query is an {@link AbsoluteFormQuery} containing a single line for one person. This should correspond to {@link EntityPreviewForm#VALUES_QUERY_NAME}. */ - private List transformQueryResultToInfos(ManagedQuery infoCardExecution, PrintSettings printSettings) { + private List transformQueryResultToInfos( + ManagedQuery infoCardExecution, PrintSettings printSettings, PrinterFactory printerFactory) { // Submitted Query is a single line of an AbsoluteFormQuery => MultilineEntityResult with a single line. @@ -259,18 +122,25 @@ private List transformQueryResultToInfos(ManagedQuery final List extraInfos = new ArrayList<>(values.length); // We are only interested in the Select results. - for (int index = AbsoluteFormQuery.FEATURES_OFFSET; index < infoCardExecution.getResultInfos(printSettings).size(); index++) { - final ResultInfo resultInfo = infoCardExecution.getResultInfos(printSettings).get(index); + for (int index = AbsoluteFormQuery.FEATURES_OFFSET; index < infoCardExecution.getResultInfos().size(); index++) { + final ResultInfo resultInfo = infoCardExecution.getResultInfos().get(index); + final Object value = values[index]; + final Object printed; - final Object printed = renderValue(values[index], resultInfo.getType(), printSettings); + if (value == null) { + printed = null; + } + else { + Printer printer = resultInfo.createPrinter(printerFactory, printSettings); + printed = printer.apply(value); + } - extraInfos.add(new EntityPreviewStatus.Info( - resultInfo.userColumnName(), - printed, - resultInfo.getType().typeInfo(), - resultInfo.getDescription(), - resultInfo.getSemantics() + extraInfos.add(new EntityPreviewStatus.Info(resultInfo.userColumnName(printSettings), + printed, + resultInfo.getType().typeInfo(), + resultInfo.getDescription(), + resultInfo.getSemantics() )); } @@ -283,7 +153,8 @@ private ManagedQuery getInfoCardExecution() { } @NotNull - private List toChronoInfos(PreviewConfig previewConfig, Map subQueries, PrintSettings printSettings) { + private List toChronoInfos( + PreviewConfig previewConfig, Map subQueries, PrintSettings printSettings, PrinterFactory printers) { final List timeStratifiedInfos = new ArrayList<>(); for (PreviewConfig.TimeStratifiedSelects description : previewConfig.getTimeStratifiedSelects()) { @@ -292,22 +163,24 @@ private List toChronoInfos(PreviewConfi final EntityResult entityResult = query.streamResults(OptionalLong.empty()).collect(MoreCollectors.onlyElement()); final Map select2desc = - description.selects().stream() - .collect(Collectors.toMap(PreviewConfig.InfoCardSelect::select, Function.identity())); + description.selects().stream().collect(Collectors.toMap(PreviewConfig.InfoCardSelect::select, Function.identity())); // Group lines by year and quarter. - final Function> lineTransformer = createLineToMapTransformer(query.getResultInfos(printSettings), select2desc, printSettings); + final Function> lineTransformer = createLineToMapTransformer(query.getResultInfos(), select2desc, printSettings, printers); final List yearEntries = createYearEntries(entityResult, lineTransformer); final Object[] completeResult = getCompleteLine(entityResult); // get descriptions, but drop everything that isn't a select result as the rest is already structured - final List columnDescriptors = createChronoColumnDescriptors(query, select2desc, printSettings); + final List columnDescriptors = createChronoColumnDescriptors(query, select2desc); - final EntityPreviewStatus.TimeStratifiedInfos - infos = - new EntityPreviewStatus.TimeStratifiedInfos(description.label(), description.description(), columnDescriptors, lineTransformer.apply(completeResult), yearEntries); + final EntityPreviewStatus.TimeStratifiedInfos infos = new EntityPreviewStatus.TimeStratifiedInfos(description.label(), + description.description(), + columnDescriptors, + lineTransformer.apply(completeResult), + yearEntries + ); timeStratifiedInfos.add(infos); } @@ -315,6 +188,51 @@ private List toChronoInfos(PreviewConfi return timeStratifiedInfos; } + /** + * Creates a transformer printing lines, transformed into a Map of label->value. + * Null values are omitted. + */ + private static Function> createLineToMapTransformer( + List resultInfos, Map select2desc, PrintSettings printSettings, PrinterFactory printerFactory) { + + + final int size = resultInfos.size(); + final String[] columnNames = new String[size]; + final Printer[] printers = new Printer[size]; + + for (int index = 0; index < size; index++) { + final ResultInfo resultInfo = resultInfos.get(index); + + if (resultInfo instanceof SelectResultInfo selectResultInfo) { + columnNames[index] = select2desc.get(selectResultInfo.getSelect().getId()).label(); + } + + printers[index] = resultInfo.createPrinter(printerFactory, printSettings); + } + + return line -> { + final Map out = new HashMap<>(size); + + for (int column = 0; column < size; column++) { + final String columnName = columnNames[column]; + + if (columnName == null) { + continue; + } + + if (line[column] == null) { + continue; + } + + final Object value = printers[column].apply(line[column]); + + out.put(columnName, value); + } + + return out; + }; + } + @NotNull private List createYearEntries(EntityResult entityResult, Function> lineTransformer) { final Map yearLines = getYearLines(entityResult); @@ -341,18 +259,84 @@ private List createYearEntries(EntityResult entit private Object[] getCompleteLine(EntityResult entityResult) { for (Object[] line : entityResult.listResultLines()) { + if (Resolution.valueOf((String) line[AbsoluteFormQuery.RESOLUTION_INDEX]) == Resolution.COMPLETE) { + return line; + } + } + + throw new IllegalStateException("Result has no row for COMPLETE"); + } + + /** + * For the selects in result infos, build ColumnDescriptors using definitions (label and description) from PreviewConfig. + */ + private static List createChronoColumnDescriptors(SingleTableResult query, Map select2desc) { + + final List columnDescriptions = new ArrayList<>(); + + for (ResultInfo info : query.getResultInfos()) { + if (info instanceof SelectResultInfo selectResultInfo) { + final PreviewConfig.InfoCardSelect desc = select2desc.get(selectResultInfo.getSelect().getId()); + + // We build these by hand because they are labeled and described by config. + columnDescriptions.add(new ColumnDescriptor(desc.label(), + desc.label(), + desc.description() != null ? desc.description() : selectResultInfo.getDescription(), // both might be null + info.getType().typeInfo(), + info.getSemantics() + )); + } + } + + + return columnDescriptions; + } + + /** + * Query contains both YEARS and QUARTERS lines: Group them. + */ + private static Map getYearLines(EntityResult entityResult) { + + final Map yearLines = new HashMap<>(); + + for (Object[] line : entityResult.listResultLines()) { + + if (Resolution.valueOf((String) line[AbsoluteFormQuery.RESOLUTION_INDEX]) != Resolution.YEARS) { + continue; + } + // Since we know the dates are always aligned we need to only respect their starts. final LocalDate date = CDate.toLocalDate(((List) line[AbsoluteFormQuery.TIME_INDEX]).get(0)); final int year = date.getYear(); - final int quarter = QuarterUtils.getQuarter(date); - if (Resolution.valueOf((String) line[AbsoluteFormQuery.RESOLUTION_INDEX]) == Resolution.COMPLETE) { - return line; + yearLines.put(year, line); + } + + return yearLines; + } + + /** + * Query contains both YEARS and QUARTERS lines: Group them. + */ + private static Map> getQuarterLines(EntityResult entityResult) { + final Map> quarterLines = new HashMap<>(); + + for (Object[] line : entityResult.listResultLines()) { + if (Resolution.valueOf((String) line[AbsoluteFormQuery.RESOLUTION_INDEX]) != Resolution.QUARTERS) { + continue; } + + // Since we know the dates are always aligned we need to only respect their starts. + final LocalDate date = CDate.toLocalDate(((List) line[AbsoluteFormQuery.TIME_INDEX]).get(0)); + + final int year = date.getYear(); + final int quarter = QuarterUtils.getQuarter(date); + + quarterLines.computeIfAbsent(year, (ignored) -> new HashMap<>(4)).put(quarter, line); } - throw new IllegalStateException("Result has no row for COMPLETE"); + return quarterLines; } protected void setAdditionalFieldsForStatusWithColumnDescription(Subject subject, FullExecutionStatus status) { @@ -367,8 +351,7 @@ public List generateColumnDescriptions(boolean isInitialized, // Add grouping semantics to secondaryIds to group by if (descriptor.getSemantics() .stream() - .anyMatch(semanticType -> semanticType instanceof SemanticType.SecondaryIdT desc - && previewConfig.isGroupingColumn(desc.getSecondaryId()))) { + .anyMatch(semanticType -> semanticType instanceof SemanticType.SecondaryIdT desc && previewConfig.isGroupingColumn(desc.getSecondaryId()))) { descriptor.getSemantics().add(new SemanticType.GroupT()); } @@ -384,19 +367,14 @@ public List generateColumnDescriptions(boolean isInitialized, return descriptors; } - @JsonIgnore - private ManagedQuery getValuesQuery() { - return getSubQueries().get(EntityPreviewForm.VALUES_QUERY_NAME); - } - @Override protected void setAdditionalFieldsForStatusWithSource(Subject subject, FullExecutionStatus status, Namespace namespace) { status.setColumnDescriptions(generateColumnDescriptions(isInitialized(), getConfig())); } @Override - public List getResultInfos(PrintSettings printSettings) { - return getValuesQuery().getResultInfos(printSettings); + public List getResultInfos() { + return getValuesQuery().getResultInfos(); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/MultiSelectAggregator.java b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/MultiSelectAggregator.java deleted file mode 100644 index f428a0167c..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/MultiSelectAggregator.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.bakdata.conquery.models.query.queryplan.aggregators.specific; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import com.bakdata.conquery.models.datasets.Column; -import com.bakdata.conquery.models.events.Bucket; -import com.bakdata.conquery.models.query.QueryExecutionContext; -import com.bakdata.conquery.models.query.entity.Entity; -import com.bakdata.conquery.models.query.queryplan.aggregators.SingleColumnAggregator; -import lombok.ToString; - -/** - * Aggregator counting the occurrence of multiple values. - */ -@ToString(callSuper = true, of = "selection") -public class MultiSelectAggregator extends SingleColumnAggregator> { - - private final String[] selection; - private final int[] hits; - - public MultiSelectAggregator(Column column, String[] selection) { - super(column); - this.selection = selection; - this.hits = new int[selection.length]; - } - - @Override - public void init(Entity entity, QueryExecutionContext context) { - Arrays.fill(hits, 0); - } - - @Override - public void nextBlock(Bucket bucket) { - } - - @Override - public void consumeEvent(Bucket bucket, int event) { - if (!bucket.has(event, getColumn())) { - return; - } - - String stringToken = bucket.getString(event, getColumn()); - - for (int index = 0; index < selection.length; index++) { - if (Objects.equals(selection[index], stringToken)) { - hits[index]++; - return; - } - } - } - - @Override - public Map createAggregationResult() { - Map out = new HashMap<>(); - - for (int i = 0; i < hits.length; i++) { - int hit = hits[i]; - if (hit > 0) { - out.merge(selection[i], hit, Integer::sum); - } - } - - return out.isEmpty() ? null : out; - } - - @Override - public boolean isOfInterest(Bucket bucket) { -//TODO - // for (String selected : selection) { -// if (((StringStore) bucket.getStores()[getColumn().getPosition()]).getId(selected) == -1) { -// return false; -// } -// } - - return super.isOfInterest(bucket); - } -} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/SelectAggregator.java b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/SelectAggregator.java deleted file mode 100644 index d654d03ad2..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/SelectAggregator.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.bakdata.conquery.models.query.queryplan.aggregators.specific; - -import java.util.Objects; - -import com.bakdata.conquery.models.datasets.Column; -import com.bakdata.conquery.models.events.Bucket; -import com.bakdata.conquery.models.query.QueryExecutionContext; -import com.bakdata.conquery.models.query.entity.Entity; -import com.bakdata.conquery.models.query.queryplan.aggregators.SingleColumnAggregator; -import lombok.ToString; - - -/** - * Aggregator counting the number of occurrences of a selected value in a column. - */ -@ToString(callSuper = true, of = {"selected"}) -public class SelectAggregator extends SingleColumnAggregator { - - private final String selected; - private long hits = 0; - - public SelectAggregator(Column column, String selected) { - super(column); - this.selected = selected; - } - - @Override - public void init(Entity entity, QueryExecutionContext context) { - hits = 0; - } - - @Override - public void nextBlock(Bucket bucket) { - } - - @Override - public void consumeEvent(Bucket bucket, int event) { - - if (!bucket.has(event, getColumn())) { - return; - } - - final String value = bucket.getString(event, getColumn()); - - if (Objects.equals(value, selected)) { - hits++; - } - } - - @Override - public Long createAggregationResult() { - return hits > 0 ? hits : null; - } - - @Override - public boolean isOfInterest(Bucket bucket) { - return super.isOfInterest(bucket); - //TODO && ((StringStore) bucket.getStores()[getColumn().getPosition()]).getId(selected) != -1; - } -} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/diffsum/MoneyDiffSumAggregator.java b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/diffsum/MoneyDiffSumAggregator.java index 1a1edf8d17..7360e7ad0c 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/diffsum/MoneyDiffSumAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/diffsum/MoneyDiffSumAggregator.java @@ -1,5 +1,6 @@ package com.bakdata.conquery.models.query.queryplan.aggregators.specific.diffsum; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; @@ -15,13 +16,13 @@ * Aggregator summing over {@code addendColumn} and subtracting over {@code subtrahendColumn}, for money columns. */ @ToString(of = {"addendColumn", "subtrahendColumn"}) -public class MoneyDiffSumAggregator extends ColumnAggregator { +public class MoneyDiffSumAggregator extends ColumnAggregator { @Getter private final Column addendColumn; @Getter private final Column subtrahendColumn; - private long sum; + private BigDecimal sum; private boolean hit; public MoneyDiffSumAggregator(Column addend, Column subtrahend) { @@ -32,7 +33,7 @@ public MoneyDiffSumAggregator(Column addend, Column subtrahend) { @Override public void init(Entity entity, QueryExecutionContext context) { hit = false; - sum = 0; + sum = BigDecimal.ZERO; } @@ -55,15 +56,15 @@ public void consumeEvent(Bucket bucket, int event) { hit = true; - long addend = bucket.has(event, getAddendColumn()) ? bucket.getMoney(event, getAddendColumn()) : 0; + final BigDecimal addend = bucket.has(event, getAddendColumn()) ? bucket.getMoney(event, getAddendColumn()) : BigDecimal.ZERO; - long subtrahend = bucket.has(event, getSubtrahendColumn()) ? bucket.getMoney(event, getSubtrahendColumn()) : 0; + final BigDecimal subtrahend = bucket.has(event, getSubtrahendColumn()) ? bucket.getMoney(event, getSubtrahendColumn()) : BigDecimal.ZERO; - sum = sum + addend - subtrahend; + sum = sum.add(addend).subtract(subtrahend); } @Override - public Long createAggregationResult() { + public BigDecimal createAggregationResult() { return hit ? sum : null; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/sum/MoneySumAggregator.java b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/sum/MoneySumAggregator.java index f9d0fc46be..facec8f618 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/sum/MoneySumAggregator.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/queryplan/aggregators/specific/sum/MoneySumAggregator.java @@ -1,5 +1,7 @@ package com.bakdata.conquery.models.query.queryplan.aggregators.specific.sum; +import java.math.BigDecimal; + import com.bakdata.conquery.models.datasets.Column; import com.bakdata.conquery.models.events.Bucket; import com.bakdata.conquery.models.query.QueryExecutionContext; @@ -11,10 +13,10 @@ * Aggregator implementing a sum over {@code column}, for money columns. */ @ToString(callSuper = true, onlyExplicitlyIncluded = true) -public class MoneySumAggregator extends SingleColumnAggregator { +public class MoneySumAggregator extends SingleColumnAggregator { private boolean hit = false; - private long sum = 0L; + private BigDecimal sum; public MoneySumAggregator(Column column) { super(column); @@ -23,7 +25,7 @@ public MoneySumAggregator(Column column) { @Override public void init(Entity entity, QueryExecutionContext context) { hit = false; - sum = 0; + sum = BigDecimal.ZERO; } @@ -35,13 +37,13 @@ public void consumeEvent(Bucket bucket, int event) { hit = true; - long addend = bucket.getMoney(event, getColumn()); + final BigDecimal addend = bucket.getMoney(event, getColumn()); - sum = sum + addend; + sum = sum.add(addend); } @Override - public Long createAggregationResult() { + public BigDecimal createAggregationResult() { return hit ? sum : null; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java index b1d8abc4f5..96faaa22f3 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ColumnResultInfo.java @@ -1,12 +1,14 @@ package com.bakdata.conquery.models.query.resultinfo; -import java.util.Set; +import java.util.Collections; import com.bakdata.conquery.models.datasets.Column; +import com.bakdata.conquery.models.datasets.concepts.Concept; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.common.ConceptIdPrinter; import com.bakdata.conquery.models.types.ResultType; -import com.bakdata.conquery.models.types.SemanticType; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; @@ -19,25 +21,33 @@ public class ColumnResultInfo extends ResultInfo { private final Column column; private final ResultType type; private final String description; - private final ResultPrinters.Printer printer; + private final Concept concept; - public ColumnResultInfo(Column column, ResultType type, Set semantics, ResultPrinters.Printer printer, String description, PrintSettings settings) { - super(semantics, settings); + public ColumnResultInfo(Column column, ResultType type, String description, Concept concept) { + super(Collections.emptySet()); this.column = column; this.type = type; this.description = description; - this.printer = printer; + this.concept = concept; } @Override - public String userColumnName() { + public String userColumnName(PrintSettings printSettings) { return column.getTable().getLabel() + " " + column.getLabel(); } @Override - public String defaultColumnName() { - return userColumnName(); + public String defaultColumnName(PrintSettings printSettings) { + return userColumnName(printSettings); + } + + @Override + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + if(concept != null){ + return new ConceptIdPrinter(concept, printSettings); + } + return printerFactory.printerFor(type, printSettings); } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java index 984840fd5c..f5900aae5a 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ExternalResultInfo.java @@ -1,12 +1,11 @@ package com.bakdata.conquery.models.query.resultinfo; import java.util.Collections; -import java.util.Set; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; -import com.bakdata.conquery.models.types.SemanticType; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -16,28 +15,30 @@ public class ExternalResultInfo extends ResultInfo { private final String name; private final ResultType type; - private final String description; - private final ResultPrinters.Printer printer; - public ExternalResultInfo(String name, ResultType type, PrintSettings settings) { - this(name, type, null, ResultPrinters.printerFor(type, settings), Collections.emptySet(), settings); - } - public ExternalResultInfo(String name, ResultType type, String description, ResultPrinters.Printer printer, Set semantics, PrintSettings settings) { - super(semantics, settings); + public ExternalResultInfo(String name, ResultType type) { + super(Collections.emptySet()); this.name = name; this.type = type; - this.description = description; - this.printer = printer; } - @Override - public String userColumnName() { + public String userColumnName(PrintSettings printSettings) { return null; } @Override - public String defaultColumnName() { + public String defaultColumnName(PrintSettings printSettings) { return name; } + + @Override + public String getDescription() { + return null; + } + + @Override + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + return printerFactory.printerFor(type, printSettings); + } } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/FixedLabelResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/FixedLabelResultInfo.java index 8a4b898115..8e09dd8d79 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/FixedLabelResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/FixedLabelResultInfo.java @@ -4,12 +4,12 @@ import c10n.C10N; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import lombok.EqualsAndHashCode; import lombok.Getter; -import lombok.NonNull; import lombok.ToString; /** @@ -34,35 +34,28 @@ */ @EqualsAndHashCode(callSuper = true) @ToString -public class FixedLabelResultInfo extends ResultInfo { +public abstract class FixedLabelResultInfo extends ResultInfo { - @NonNull - private final String localizedLabel; - @NonNull - private final String localizedDefaultLabel; - @Getter - private final ResultType type; @Getter - private final ResultPrinters.Printer printer; + private final ResultType type; - public FixedLabelResultInfo(String label, String defaultLabel, ResultType type, Set semantics, PrintSettings settings, ResultPrinters.Printer printer) { - super(semantics, settings); - this.localizedLabel = label; - this.localizedDefaultLabel = defaultLabel; + public FixedLabelResultInfo(ResultType type, Set semantics) { + super(semantics); this.type = type; - this.printer = printer; } - @Override - public String userColumnName() { - return localizedLabel; + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + return printerFactory.printerFor(getType(), printSettings); } @Override - public String defaultColumnName() { - return localizedDefaultLabel; + public abstract String userColumnName(PrintSettings printSettings); + + @Override + public String defaultColumnName(PrintSettings printSettings) { + return userColumnName(printSettings); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java index 54a68b428b..9774dbe390 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/ResultInfo.java @@ -7,7 +7,8 @@ import com.bakdata.conquery.models.query.ColumnDescriptor; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import com.google.common.collect.ImmutableSet; @@ -24,13 +25,10 @@ @Slf4j public abstract class ResultInfo { - private final PrintSettings settings; - @ToString.Include private final Set semantics = new HashSet<>(); - protected ResultInfo(Collection semantics, PrintSettings settings) { - this.settings = settings; + protected ResultInfo(Collection semantics) { this.semantics.addAll(semantics); } @@ -38,12 +36,12 @@ public final void addSemantics(SemanticType... incoming) { semantics.addAll(Arrays.asList(incoming)); } - public abstract String userColumnName(); + public abstract String userColumnName(PrintSettings printSettings); - public final ColumnDescriptor asColumnDescriptor(UniqueNamer collector) { + public final ColumnDescriptor asColumnDescriptor(UniqueNamer collector, PrintSettings printSettings) { return new ColumnDescriptor( - collector.getUniqueName(this), - defaultColumnName(), getDescription(), + collector.getUniqueName(this, printSettings), + defaultColumnName(printSettings), getDescription(), getType().typeInfo(), getSemantics() ); @@ -51,8 +49,9 @@ public final ColumnDescriptor asColumnDescriptor(UniqueNamer collector) { /** * Use default label schema which ignores user labels. + * @param printSettings */ - public abstract String defaultColumnName(); + public abstract String defaultColumnName(PrintSettings printSettings); @ToString.Include public abstract ResultType getType(); @@ -63,17 +62,5 @@ public Set getSemantics() { public abstract String getDescription(); - public final String printNullable(Object f) { - if (f == null) { - return ""; - } - - return print(f); - } - - protected String print(Object f) { - return getPrinter().print(f); - } - - public abstract ResultPrinters.Printer getPrinter(); + public abstract Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java new file mode 100644 index 0000000000..a50a4efea7 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SecondaryIdResultInfo.java @@ -0,0 +1,54 @@ +package com.bakdata.conquery.models.query.resultinfo; + +import java.util.Set; + +import com.bakdata.conquery.models.datasets.SecondaryIdDescription; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.common.MappedPrinter; +import com.bakdata.conquery.models.types.ResultType; +import com.bakdata.conquery.models.types.SemanticType; +import lombok.Getter; +import lombok.ToString; + +@Getter +@ToString +public class SecondaryIdResultInfo extends ResultInfo { + private final SecondaryIdDescription secondaryId; + private final ResultType type; + + + public SecondaryIdResultInfo(SecondaryIdDescription secondaryId) { + super(Set.of(new SemanticType.SecondaryIdT(secondaryId))); + this.secondaryId = secondaryId; + type = ResultType.Primitive.STRING; + + + } + + @Override + public String getDescription() { + return secondaryId.getDescription(); + } + + @Override + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + if (secondaryId.getMapping() == null) { + return printerFactory.getStringPrinter(printSettings); + } + else { + return new MappedPrinter(secondaryId.getMapping()); + } + } + + @Override + public String userColumnName(PrintSettings printSettings) { + return secondaryId.getLabel(); + } + + @Override + public String defaultColumnName(PrintSettings printSettings) { + return userColumnName(printSettings); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java index b8873c64d4..33db8e3e8c 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/SelectResultInfo.java @@ -5,7 +5,8 @@ import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; import com.google.common.collect.Sets; @@ -21,8 +22,8 @@ public class SelectResultInfo extends ResultInfo { @NonNull private final CQConcept cqConcept; - public SelectResultInfo(Select select, CQConcept cqConcept, Set semantics, PrintSettings settings) { - super(Sets.union(semantics, Set.of(new SemanticType.SelectResultT(select))), settings); + public SelectResultInfo(Select select, CQConcept cqConcept, Set semantics) { + super(Sets.union(semantics, Set.of(new SemanticType.SelectResultT(select)))); this.select = select; this.cqConcept = cqConcept; } @@ -34,8 +35,8 @@ public String getDescription() { } @Override - public ResultPrinters.Printer getPrinter() { - return select.createPrinter(getSettings()); + public Printer createPrinter(PrinterFactory printerFactory, PrintSettings printSettings) { + return select.createPrinter(printerFactory, printSettings); } @Override @@ -44,11 +45,11 @@ public ResultType getType() { } @Override - public String userColumnName() { + public String userColumnName(PrintSettings printSettings) { - if (getSettings().getColumnNamer() != null) { + if (printSettings.getColumnNamer() != null) { // override user labels if column namer is set, TODO clean this up when userConceptLabel is removed - return getSettings().getColumnNamer().apply(this); + return printSettings.getColumnNamer().apply(this); } String label = getCqConcept().getLabel(); @@ -60,10 +61,10 @@ public String userColumnName() { } @Override - public String defaultColumnName() { + public String defaultColumnName(PrintSettings printSettings) { StringBuilder sb = new StringBuilder(); - String cqLabel = getCqConcept().defaultLabel(getSettings().getLocale()); + String cqLabel = getCqConcept().defaultLabel(printSettings.getLocale()); final String selectLabel = select.getColumnName(); if (selectLabel.equals(cqLabel)) { diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/UniqueNamer.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/UniqueNamer.java index 9b11596c33..12218e1edf 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/UniqueNamer.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/UniqueNamer.java @@ -33,9 +33,9 @@ public class UniqueNamer { @NonNull @JsonIgnore - public final String getUniqueName(ResultInfo info) { + public final String getUniqueName(ResultInfo info, PrintSettings printSettings) { @NonNull - String label = Objects.requireNonNullElse(info.userColumnName(), info.defaultColumnName()); + String label = Objects.requireNonNullElse(info.userColumnName(printSettings), info.defaultColumnName(printSettings)); // lookup if prefix is needed and computed it if necessary String uniqueName = label; synchronized (ocurrenceCounter) { diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ArrowResultPrinters.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ArrowResultPrinters.java new file mode 100644 index 0000000000..9e1a4ecffe --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ArrowResultPrinters.java @@ -0,0 +1,31 @@ +package com.bakdata.conquery.models.query.resultinfo.printers; + +import java.math.BigDecimal; + +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.common.IdentityPrinter; +import org.jetbrains.annotations.NotNull; + +public class ArrowResultPrinters extends JavaResultPrinters { + + @Override + public Printer getDatePrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + @Override + public Printer getMoneyPrinter(PrintSettings printSettings) { + return new MoneyPrinter(); + } + + private record MoneyPrinter() implements Printer { + @Override + public Object apply(@NotNull Number value) { + if (value instanceof BigDecimal bigDecimal){ + return bigDecimal.unscaledValue().intValueExact(); + } + + return value.intValue(); + } + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ExcelResultPrinters.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ExcelResultPrinters.java new file mode 100644 index 0000000000..4a9e05a0ad --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ExcelResultPrinters.java @@ -0,0 +1,59 @@ +package com.bakdata.conquery.models.query.resultinfo.printers; + +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.common.DatePrinter; +import com.bakdata.conquery.models.query.resultinfo.printers.common.IdentityPrinter; +import com.bakdata.conquery.models.types.ResultType; + +/** + * This class is a mess because Excel supports some of our types natively. + * + * With LIST types we fall back onto the StringResultPrinter, as Excel does not support Lists, BUT we also cannot use the {@link IdentityPrinter} inside the list, as some of our printers are native types. + */ +public class ExcelResultPrinters extends StringResultPrinters { + + private final PrinterFactory partialDelegate = new StringResultPrinters(); + + public Printer printerFor(ResultType type, PrintSettings printSettings) { + if (type instanceof ResultType.ListT listT) { + final Printer elementPrinter = partialDelegate.printerFor(listT.getElementType(), printSettings); + return getListPrinter(elementPrinter, printSettings); + } + + return switch (((ResultType.Primitive) type)) { + case BOOLEAN -> getBooleanPrinter(printSettings); + case INTEGER -> getIntegerPrinter(printSettings); + case NUMERIC -> getNumericPrinter(printSettings); + case DATE -> getDatePrinter(printSettings); + case DATE_RANGE -> getDateRangePrinter(printSettings); + case STRING -> getStringPrinter(printSettings); + case MONEY -> getMoneyPrinter(printSettings); + }; + } + + @Override + public Printer getBooleanPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + @Override + public Printer getNumericPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + @Override + public Printer getMoneyPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + @Override + public Printer getDatePrinter(PrintSettings printSettings) { + return new DatePrinter(); + } + + @Override + public Printer getIntegerPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JavaResultPrinters.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JavaResultPrinters.java new file mode 100644 index 0000000000..bab9fc5153 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JavaResultPrinters.java @@ -0,0 +1,76 @@ +package com.bakdata.conquery.models.query.resultinfo.printers; + +import java.util.ArrayList; +import java.util.List; + +import com.bakdata.conquery.models.common.daterange.CDateRange; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.common.DatePrinter; +import com.bakdata.conquery.models.query.resultinfo.printers.common.IdentityPrinter; +import org.jetbrains.annotations.NotNull; + +public class JavaResultPrinters extends PrinterFactory { + + @Override + public Printer> getListPrinter(Printer elementPrinter, PrintSettings printSettings) { + return new ListPrinter<>(elementPrinter); + } + + @Override + public Printer getBooleanPrinter(PrintSettings printSettings) { + return new IdentityPrinter(); + } + + @Override + public Printer getIntegerPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + @Override + public Printer getNumericPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + @Override + public Printer getDatePrinter(PrintSettings printSettings) { + return new DatePrinter(); + } + + @Override + public Printer> getDateRangePrinter(PrintSettings printSettings) { + return new DateRangePrinter(); + } + + @Override + public Printer getStringPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + + @Override + public Printer getMoneyPrinter(PrintSettings printSettings) { + return new IdentityPrinter<>(); + } + + private record ListPrinter(Printer elementPrinter) implements Printer> { + + @Override + public Object apply(@NotNull List value) { + final List out = new ArrayList<>(value.size()); + + for (T elt : value) { + out.add(elementPrinter.apply(elt)); + } + + return out; + } + } + + private record DateRangePrinter() implements Printer> { + + @Override + public Object apply(@NotNull List f) { + return CDateRange.of(f.get(0), f.get(1)); + } + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JsonResultPrinters.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JsonResultPrinters.java new file mode 100644 index 0000000000..69dd30b38c --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/JsonResultPrinters.java @@ -0,0 +1,27 @@ +package com.bakdata.conquery.models.query.resultinfo.printers; + +import java.util.List; + +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.common.ToStringPrinter; +import lombok.ToString; + +/** + * This class simply put's out native types where possible to let Jackson handle the Serialization, except for Date and DateRange, where the Frontend cannot ensure proper handling. + */ +@ToString +public class JsonResultPrinters extends JavaResultPrinters { + + + @Override + public Printer getDatePrinter(PrintSettings printSettings) { + return new ToStringPrinter<>(super.getDatePrinter(printSettings)); + } + + @Override + public Printer> getDateRangePrinter(PrintSettings printSettings) { + return new ToStringPrinter<>(super.getDateRangePrinter(printSettings)); + } + + +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/Printer.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/Printer.java new file mode 100644 index 0000000000..b165df89ea --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/Printer.java @@ -0,0 +1,15 @@ +package com.bakdata.conquery.models.query.resultinfo.printers; + +import java.util.function.Function; + +import org.jetbrains.annotations.NotNull; + +/** + * Printers handle transformation from {@link com.bakdata.conquery.models.query.results.EntityResult} to the respective renderers "native" representation. + * + * @param The intermediate representation of the type we are printing. + */ +@FunctionalInterface +public interface Printer extends Function { + Object apply(@NotNull T value); +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/PrinterFactory.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/PrinterFactory.java new file mode 100644 index 0000000000..2d46e73c68 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/PrinterFactory.java @@ -0,0 +1,56 @@ +package com.bakdata.conquery.models.query.resultinfo.printers; + +import java.util.List; + +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.types.ResultType; + +/** + * This class allows {@link com.bakdata.conquery.models.datasets.concepts.select.Select}s to abstractly define printing, for all our renderers. + * + * The primary thing this class solves is {@link List} printing interacting with special handling like {@link com.bakdata.conquery.models.datasets.concepts.select.concept.ConceptColumnSelect} and {@link com.bakdata.conquery.models.datasets.concepts.select.connector.specific.MappableSingleColumnSelect}. + */ +public abstract class PrinterFactory { + /** + * Default implementation of determining the printer for a {@link ResultType}. + * Generally, this method should not be overriden and preferably be final, but {@link ExcelResultPrinters} makes this problematic. + */ + public Printer printerFor(ResultType type, PrintSettings printSettings) { + if (type instanceof ResultType.ListT listT) { + final Printer elementPrinter = printerFor(listT.getElementType(), printSettings); + return (Printer) getListPrinter(elementPrinter, printSettings); + } + + return (Printer) switch (((ResultType.Primitive) type)) { + case BOOLEAN -> getBooleanPrinter(printSettings); + case INTEGER -> getIntegerPrinter(printSettings); + case NUMERIC -> getNumericPrinter(printSettings); + case DATE -> getDatePrinter(printSettings); + case DATE_RANGE -> getDateRangePrinter(printSettings); + case STRING -> getStringPrinter(printSettings); + case MONEY -> getMoneyPrinter(printSettings); + }; + } + + public abstract Printer> getListPrinter(Printer elementPrinter, PrintSettings printSettings); + + public abstract Printer getBooleanPrinter(PrintSettings printSettings); + + /** + * Jackson will opportunistically read {@link Long} and {@link Integer} hence our usage of Number. + */ + public abstract Printer getIntegerPrinter(PrintSettings printSettings); + + public abstract Printer getNumericPrinter(PrintSettings printSettings); + + /** + * Jackson will opportunistically read {@link Long} and {@link Integer} hence our usage of Number. + */ + public abstract Printer getDatePrinter(PrintSettings printSettings); + + public abstract Printer> getDateRangePrinter(PrintSettings printSettings); + + public abstract Printer getStringPrinter(PrintSettings printSettings); + + public abstract Printer getMoneyPrinter(PrintSettings printSettings); +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ResultPrinters.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ResultPrinters.java deleted file mode 100644 index 8cc0a3208b..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/ResultPrinters.java +++ /dev/null @@ -1,231 +0,0 @@ -package com.bakdata.conquery.models.query.resultinfo.printers; - -import java.math.BigDecimal; -import java.text.NumberFormat; -import java.util.List; -import java.util.Objects; -import java.util.StringJoiner; - -import com.bakdata.conquery.internationalization.Results; -import com.bakdata.conquery.models.common.CDate; -import com.bakdata.conquery.models.common.LocalizedToString; -import com.bakdata.conquery.models.common.daterange.CDateRange; -import com.bakdata.conquery.models.config.LocaleConfig; -import com.bakdata.conquery.models.datasets.concepts.Concept; -import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeNode; -import com.bakdata.conquery.models.datasets.concepts.tree.TreeConcept; -import com.bakdata.conquery.models.index.InternToExternMapper; -import com.bakdata.conquery.models.query.C10nCache; -import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.types.ResultType; -import com.google.common.base.Preconditions; -import lombok.experimental.UtilityClass; -import lombok.extern.slf4j.Slf4j; - -@UtilityClass -@Slf4j -public class ResultPrinters { - - public Printer printerFor(ResultType type, PrintSettings printSettings) { - if (type instanceof ResultType.ListT listT) { - return new ListPrinter(printerFor(listT.getElementType(), printSettings), printSettings); - } - - return switch (((ResultType.Primitive) type)) { - case BOOLEAN -> new BooleanPrinter(printSettings); - case INTEGER -> NumberFormatPrinter.integerPrinter(printSettings); - case NUMERIC -> NumberFormatPrinter.decimalPrinter(printSettings); - case DATE -> new DatePrinter(printSettings); - case DATE_RANGE -> new DateRangePrinter(printSettings); - case STRING -> new StringPrinter(); - case MONEY -> MoneyPrinter.create(printSettings); - }; - } - - public BigDecimal readMoney(PrintSettings cfg, Number value) { - return new BigDecimal(value.longValue()).movePointLeft(cfg.getCurrency().getDefaultFractionDigits()); - } - - public interface Printer { - String print(Object f); - } - - public record StringPrinter() implements Printer { - @Override - public String print(Object f) { - return Objects.toString(f); - } - } - - public record NumberFormatPrinter(NumberFormat format) implements Printer { - - public static Printer integerPrinter(PrintSettings cfg){ - if (!cfg.isPrettyPrint()) { - return new StringPrinter(); - } - - return new NumberFormatPrinter(cfg.getIntegerFormat()); - } - - public static Printer decimalPrinter(PrintSettings cfg){ - if (!cfg.isPrettyPrint()) { - return new StringPrinter(); - } - - return new NumberFormatPrinter(cfg.getDecimalFormat()); - } - - @Override - public String print(Object f) { - return format.format(f); - } - } - - public record MoneyPrinter(PrintSettings cfg, NumberFormat format) implements Printer { - - public static Printer create(PrintSettings cfg) { - if (!cfg.isPrettyPrint()) { - return new StringPrinter(); - } - - return new MoneyPrinter(cfg, (NumberFormat) cfg.getCurrencyFormat().clone()); - } - - @Override - public String print(Object f) { - final BigDecimal asMoney = readMoney(cfg, (Number) f); - return format.format(asMoney); - } - } - - public record DatePrinter(PrintSettings cfg) implements Printer { - - @Override - public String print(Object f) { - Preconditions.checkArgument(f instanceof Number, "Expected an Number but got an '%s' with the value: %s".formatted(f.getClass().getName(), f)); - - final Number number = (Number) f; - return cfg.getDateFormatter().format(CDate.toLocalDate(number.intValue())); - } - } - - public record DateRangePrinter(DatePrinter datePrinter, PrintSettings cfg) implements Printer { - - public DateRangePrinter(PrintSettings printSettings) { - this(new DatePrinter(printSettings), printSettings); - } - - @Override - public String print(Object f) { - Preconditions.checkArgument(f instanceof List, "Expected a List got %s (Type: %s, as string: %s)", f, f.getClass().getName(), f); - Preconditions.checkArgument(((List) f).size() == 2, "Expected a list with 2 elements, one min, one max. The list was: %s ", f); - - final List list = (List) f; - final Integer min = (Integer) list.get(0); - final Integer max = (Integer) list.get(1); - - if (min == null || max == null) { - log.warn("Encountered incomplete range, treating it as an open range. Either min or max was null: {}", list); - } - // Compute minString first because we need it either way - final String minString = min == null || min == CDateRange.NEGATIVE_INFINITY ? "-∞" : datePrinter.print(min); - - if (cfg.isPrettyPrint() && min != null && min.equals(max)) { - // If the min and max are the same we print it like a singe date, not a range (only in pretty printing) - return minString; - } - final String maxString = max == null || max == CDateRange.POSITIVE_INFINITY ? "+∞" : datePrinter.print(max); - - return minString + cfg.getDateRangeSeparator() + maxString; - } - } - - public record BooleanPrinter(PrintSettings cfg, String trueVal, String falseVal) implements Printer { - - public BooleanPrinter(PrintSettings cfg) { - this( - cfg, - cfg.isPrettyPrint() ? C10nCache.getLocalized(Results.class, cfg.getLocale()).True() : "1", - cfg.isPrettyPrint() ? C10nCache.getLocalized(Results.class, cfg.getLocale()).False() : "0" - ); - } - - @Override - public String print(Object f) { - if ((Boolean) f) { - return trueVal; - } - return falseVal; - - } - } - - public record MappedPrinter(InternToExternMapper mapper) implements Printer { - - @Override - public String print(Object f) { - return mapper.external(((String) f)); - } - } - - public record ConceptIdPrinter(Concept concept, PrintSettings cfg) implements Printer { - - @Override - public String print(Object rawValue) { - if (rawValue == null) { - return null; - } - - final int localId = (int) rawValue; - - final ConceptTreeNode node = ((TreeConcept) concept).getElementByLocalId(localId); - - if (!cfg.isPrettyPrint()) { - return node.getId().toString(); - } - - if (node.getDescription() == null) { - return node.getLabel(); - } - - return node.getLabel() + " - " + node.getDescription(); - } - } - - public record ListPrinter(Printer elementPrinter, PrintSettings cfg, LocaleConfig.ListFormat listFormat) implements Printer { - - public ListPrinter(Printer elementPrinter, PrintSettings cfg) { - this(elementPrinter, cfg, cfg.getListFormat()); - } - - @Override - public String print(Object f) { - - // Jackson deserializes collections as lists instead of an array, if the type is not given - Preconditions.checkArgument(f instanceof List, "Expected a List got %s (as String `%s` )".formatted(f.getClass().getName(), f)); - - final StringJoiner joiner = listFormat.createListJoiner(); - - for (Object obj : (List) f) { - joiner.add(listFormat.escapeListElement(elementPrinter.print(obj))); - } - return joiner.toString(); - } - } - - public record LocalizedEnumPrinter & LocalizedToString>(PrintSettings cfg, Class clazz) implements Printer { - @Override - public String print(Object f) { - - if (clazz.isInstance(f)) { - return clazz.cast(f).toString(cfg.getLocale()); - } - try { - return Enum.valueOf(clazz, f.toString()).toString(cfg.getLocale()); - } - catch (Exception e) { - throw new IllegalArgumentException("%s is not a valid %s.".formatted(f, clazz), e); - } - } - } -} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/SecondaryIdResultInfo.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/SecondaryIdResultInfo.java deleted file mode 100644 index 6f33bbb124..0000000000 --- a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/SecondaryIdResultInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.bakdata.conquery.models.query.resultinfo.printers; - -import java.util.Set; - -import com.bakdata.conquery.models.datasets.SecondaryIdDescription; -import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.types.ResultType; -import com.bakdata.conquery.models.types.SemanticType; -import lombok.Getter; -import lombok.ToString; - -@Getter -@ToString -public class SecondaryIdResultInfo extends ResultInfo { - private final SecondaryIdDescription secondaryId; - private final ResultType type; - private final ResultPrinters.Printer printer; - - - public SecondaryIdResultInfo(SecondaryIdDescription secondaryId, PrintSettings settings) { - super(Set.of(new SemanticType.SecondaryIdT(secondaryId)), settings); - this.secondaryId = secondaryId; - type = ResultType.Primitive.STRING; - printer = secondaryId.getMapping() == null - ? new ResultPrinters.StringPrinter() - : new ResultPrinters.MappedPrinter(secondaryId.getMapping()); - } - - @Override - public String getDescription() { - return secondaryId.getDescription(); - } - - @Override - public String userColumnName() { - return secondaryId.getLabel(); - } - - @Override - public String defaultColumnName() { - return userColumnName(); - } -} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/StringResultPrinters.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/StringResultPrinters.java new file mode 100644 index 0000000000..cbd74ddfaf --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/StringResultPrinters.java @@ -0,0 +1,61 @@ +package com.bakdata.conquery.models.query.resultinfo.printers; + +import java.util.List; + +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.common.BooleanStringPrinter; +import com.bakdata.conquery.models.query.resultinfo.printers.common.DateRangeStringPrinter; +import com.bakdata.conquery.models.query.resultinfo.printers.common.DateStringPrinter; +import com.bakdata.conquery.models.query.resultinfo.printers.common.ListStringPrinter; +import com.bakdata.conquery.models.query.resultinfo.printers.common.NumberFormatStringPrinter; +import com.bakdata.conquery.models.query.resultinfo.printers.common.StringPrinter; +import lombok.ToString; + +/** + * All printers in this factory should be assumed to return {@link String}, this is useful for CSV or HTML printing. + */ +@ToString +public class StringResultPrinters extends PrinterFactory { + + + @Override + public Printer> getListPrinter(Printer elementPrinter, PrintSettings printSettings) { + return new ListStringPrinter<>(elementPrinter, printSettings); + } + + @Override + public Printer getBooleanPrinter(PrintSettings printSettings) { + return BooleanStringPrinter.create(printSettings); + } + + @Override + public Printer getIntegerPrinter(PrintSettings printSettings) { + return NumberFormatStringPrinter.create(printSettings, printSettings.getIntegerFormat()); + } + + @Override + public Printer getNumericPrinter(PrintSettings printSettings) { + return NumberFormatStringPrinter.create(printSettings, printSettings.getDecimalFormat()); + } + + @Override + public Printer getDatePrinter(PrintSettings printSettings) { + return new DateStringPrinter(printSettings); + } + + @Override + public Printer> getDateRangePrinter(PrintSettings printSettings) { + return new DateRangeStringPrinter(printSettings); + } + + @Override + public Printer getStringPrinter(PrintSettings printSettings) { + return new StringPrinter(); + } + + @Override + public Printer getMoneyPrinter(PrintSettings printSettings) { + return NumberFormatStringPrinter.create(printSettings, printSettings.getCurrencyFormat()); + } + +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/BooleanStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/BooleanStringPrinter.java new file mode 100644 index 0000000000..d54fea8853 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/BooleanStringPrinter.java @@ -0,0 +1,25 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import com.bakdata.conquery.internationalization.Results; +import com.bakdata.conquery.models.query.C10nCache; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record BooleanStringPrinter(PrintSettings cfg, String trueVal, String falseVal) implements Printer { + + public static BooleanStringPrinter create(PrintSettings settings) { + if (!settings.isPrettyPrint()) { + return new BooleanStringPrinter(settings, "1", "0"); + } + + final Results localized = C10nCache.getLocalized(Results.class, settings.getLocale()); + return new BooleanStringPrinter(settings, localized.True(), localized.False()); + } + + + @Override + public String apply(@NotNull Boolean f) { + return f ? trueVal : falseVal; + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ConceptIdPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ConceptIdPrinter.java new file mode 100644 index 0000000000..e495a5110a --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ConceptIdPrinter.java @@ -0,0 +1,30 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import com.bakdata.conquery.models.datasets.concepts.Concept; +import com.bakdata.conquery.models.datasets.concepts.tree.ConceptTreeNode; +import com.bakdata.conquery.models.datasets.concepts.tree.TreeConcept; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record ConceptIdPrinter(Concept concept, PrintSettings cfg) implements Printer { + + @Override + public String apply(@NotNull Integer localId) { + if (localId == null) { + return null; + } + + final ConceptTreeNode node = ((TreeConcept) concept).getElementByLocalId(localId); + + if (!cfg.isPrettyPrint()) { + return node.getId().toString(); + } + + if (node.getDescription() == null) { + return node.getLabel(); + } + + return node.getLabel() + " - " + node.getDescription(); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DatePrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DatePrinter.java new file mode 100644 index 0000000000..d55fac0a44 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DatePrinter.java @@ -0,0 +1,13 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import com.bakdata.conquery.models.common.CDate; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record DatePrinter() implements Printer { + + @Override + public Object apply(@NotNull Number value) { + return CDate.toLocalDate(value.intValue()); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java new file mode 100644 index 0000000000..bbc8cc9d9f --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateRangeStringPrinter.java @@ -0,0 +1,37 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import java.util.List; + +import com.bakdata.conquery.models.common.daterange.CDateRange; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.google.common.base.Preconditions; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; + +@Slf4j +public record DateRangeStringPrinter(DateStringPrinter datePrinter, PrintSettings cfg) implements Printer> { + + public DateRangeStringPrinter(PrintSettings printSettings) { + this(new DateStringPrinter(printSettings), printSettings); + } + + @Override + public String apply(@NotNull List f) { + Preconditions.checkArgument(f.size() == 2, "Expected a list with 2 elements, one min, one max. The list was: %s ", f); + + final Integer min = f.get(0); + final Integer max = f.get(1); + + // Compute minString first because we need it either way + final String minString = min == null || min == CDateRange.NEGATIVE_INFINITY ? "-∞" : datePrinter.apply(min); + + if (cfg.isPrettyPrint() && min != null && min.equals(max)) { + // If the min and max are the same we print it like a singe date, not a range (only in pretty printing) + return minString; + } + final String maxString = max == null || max == CDateRange.POSITIVE_INFINITY ? "+∞" : datePrinter.apply(max); + + return minString + cfg.getDateRangeSeparator() + maxString; + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateStringPrinter.java new file mode 100644 index 0000000000..f9a57f05b5 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/DateStringPrinter.java @@ -0,0 +1,14 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import com.bakdata.conquery.models.common.CDate; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record DateStringPrinter(PrintSettings cfg) implements Printer { + + @Override + public String apply(@NotNull Number f) { + return cfg.getDateFormatter().format(CDate.toLocalDate(f.intValue())); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/IdentityPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/IdentityPrinter.java new file mode 100644 index 0000000000..30c05117e4 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/IdentityPrinter.java @@ -0,0 +1,12 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record IdentityPrinter() implements Printer { + + @Override + public Object apply(@NotNull T value) { + return value; + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java new file mode 100644 index 0000000000..f311075acb --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ListStringPrinter.java @@ -0,0 +1,31 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import java.util.List; +import java.util.StringJoiner; + +import com.bakdata.conquery.models.config.LocaleConfig; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record ListStringPrinter(Printer elementPrinter, PrintSettings cfg, LocaleConfig.ListFormat listFormat) implements Printer> { + + public ListStringPrinter(Printer elementPrinter, PrintSettings cfg) { + this(elementPrinter, cfg, cfg.getListFormat()); + } + + @Override + public String apply(@NotNull List f) { + + final StringJoiner joiner = listFormat.createListJoiner(); + + for (T obj : f) { + if (obj == null){ + continue; + } + + joiner.add(listFormat.escapeListElement(elementPrinter.apply(obj).toString())); + } + return joiner.toString(); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/LocalizedEnumPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/LocalizedEnumPrinter.java new file mode 100644 index 0000000000..61cd8ccd60 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/LocalizedEnumPrinter.java @@ -0,0 +1,18 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import com.bakdata.conquery.models.common.LocalizedToString; +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record LocalizedEnumPrinter & LocalizedToString>(PrintSettings cfg, Class clazz) implements Printer { + @Override + public String apply(@NotNull String f) { + try { + return Enum.valueOf(clazz, f).toString(cfg.getLocale()); + } + catch (Exception e) { + throw new IllegalArgumentException("%s is not a valid %s.".formatted(f, clazz), e); + } + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/MappedPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/MappedPrinter.java new file mode 100644 index 0000000000..d388ceb689 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/MappedPrinter.java @@ -0,0 +1,13 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import com.bakdata.conquery.models.index.InternToExternMapper; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record MappedPrinter(InternToExternMapper mapper) implements Printer { + + @Override + public String apply(@NotNull String f) { + return mapper.external(f); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/NumberFormatStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/NumberFormatStringPrinter.java new file mode 100644 index 0000000000..1619276295 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/NumberFormatStringPrinter.java @@ -0,0 +1,22 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import java.text.NumberFormat; + +import com.bakdata.conquery.models.query.PrintSettings; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record NumberFormatStringPrinter(NumberFormat format) implements Printer { + + public static Printer create(PrintSettings cfg, NumberFormat currencyFormat) { + if (cfg.isPrettyPrint()) { + return new NumberFormatStringPrinter(currencyFormat); + } + return new StringPrinter<>(); + } + + @Override + public String apply(@NotNull Number f) { + return format.format(f); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/StringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/StringPrinter.java new file mode 100644 index 0000000000..515b8520d1 --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/StringPrinter.java @@ -0,0 +1,13 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import java.util.Objects; + +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record StringPrinter() implements Printer { + @Override + public String apply(@NotNull T f) { + return Objects.toString(f); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ToStringPrinter.java b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ToStringPrinter.java new file mode 100644 index 0000000000..5b5c204b7b --- /dev/null +++ b/backend/src/main/java/com/bakdata/conquery/models/query/resultinfo/printers/common/ToStringPrinter.java @@ -0,0 +1,14 @@ +package com.bakdata.conquery.models.query.resultinfo.printers.common; + +import java.util.Objects; + +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import org.jetbrains.annotations.NotNull; + +public record ToStringPrinter(Printer delegate) implements Printer { + + @Override + public Object apply(@NotNull T value) { + return Objects.toString(delegate.apply(value)); + } +} diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/BooleanColumnStatsCollector.java b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/BooleanColumnStatsCollector.java index c805131751..fd4fb70237 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/BooleanColumnStatsCollector.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/BooleanColumnStatsCollector.java @@ -4,8 +4,9 @@ import java.util.Map; import c10n.C10N; +import com.bakdata.conquery.internationalization.Results; +import com.bakdata.conquery.models.query.C10nCache; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import lombok.Getter; @Getter @@ -36,13 +37,13 @@ public void consume(Object value) { @Override public ResultColumnStatistics describe() { - final ResultPrinters.BooleanPrinter printer = new ResultPrinters.BooleanPrinter(getPrintSettings()); + final Results results = C10nCache.getLocalized(Results.class, getPrintSettings().getLocale()); return new HistogramColumnDescription( getName(), getLabel(), getDescription(), List.of( - new HistogramColumnDescription.Entry(printer.print(true), trues), - new HistogramColumnDescription.Entry(printer.print(false), falses) + new HistogramColumnDescription.Entry(results.True(), trues), + new HistogramColumnDescription.Entry(results.False(), falses) ), Map.of( C10N.get(StatisticsLabels.class, getPrintSettings().getLocale()).missing(), diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ColumnStatsCollector.java b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ColumnStatsCollector.java index 28ccb85a5a..689f2e1129 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ColumnStatsCollector.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ColumnStatsCollector.java @@ -5,7 +5,6 @@ import com.bakdata.conquery.io.cps.CPSBase; import com.bakdata.conquery.models.config.FrontendConfig; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import com.bakdata.conquery.models.types.ResultType; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -19,11 +18,12 @@ public abstract class ColumnStatsCollector { @JsonIgnore private final PrintSettings printSettings; - public static ColumnStatsCollector getStatsCollector(String name, String description, ResultType type, ResultPrinters.Printer printer, PrintSettings printSettings, FrontendConfig config) { + public static ColumnStatsCollector getStatsCollector(String name, String description, ResultType type, PrintSettings printSettings, FrontendConfig config) { // List recursion must be done before assigning uniqueNames if (type instanceof ResultType.ListT listT) { - final ColumnStatsCollector columnStatsCollector = getStatsCollector(name, description, listT.getElementType(), ((ResultPrinters.ListPrinter) printer).elementPrinter(), printSettings, config); + + final ColumnStatsCollector columnStatsCollector = getStatsCollector(name, description, listT.getElementType(), printSettings, config); return new ListColumnStatsCollector(columnStatsCollector, printSettings); } @@ -31,7 +31,7 @@ public static ColumnStatsCollector getStatsCollector(String name, String descrip case BOOLEAN -> new BooleanColumnStatsCollector(name, name, description, printSettings); case INTEGER, MONEY, NUMERIC -> new NumberColumnStatsCollector<>(name, name, description, type, printSettings, config.getVisualisationsHistogramLimit(), config.getVisualisationPercentiles().lowerEndpoint(), config.getVisualisationPercentiles().upperEndpoint()); case DATE, DATE_RANGE -> new DateColumnStatsCollector(name, name, description, type, printSettings); - case STRING -> new StringColumnStatsCollector(name, name, description, printer, printSettings, config.getVisualisationsHistogramLimit()); + case STRING -> new StringColumnStatsCollector(name, name, description, printSettings, config.getVisualisationsHistogramLimit()); }; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/DateColumnStatsCollector.java b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/DateColumnStatsCollector.java index 2b56c99740..2c661d5f3d 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/DateColumnStatsCollector.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/DateColumnStatsCollector.java @@ -1,7 +1,6 @@ package com.bakdata.conquery.models.query.statistics; import java.time.LocalDate; -import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import java.util.function.Function; @@ -35,8 +34,8 @@ public DateColumnStatsCollector(String name, String label, String description, R private static Function getDateExtractor(ResultType dateType) { return switch (((ResultType.Primitive) dateType)) { - case DATE_RANGE -> dateValue -> CDateRange.fromList((List) dateValue); - case DATE -> dateValue -> CDateRange.exactly((Integer) dateValue); + case DATE_RANGE -> dateValue -> (CDateRange) dateValue; + case DATE -> dateValue -> CDateRange.exactly((LocalDate) dateValue); default -> throw new IllegalStateException("Unexpected type %s".formatted(dateType)); }; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/HistogramColumnDescription.java b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/HistogramColumnDescription.java index 708550bee6..9106859f8a 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/HistogramColumnDescription.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/HistogramColumnDescription.java @@ -12,7 +12,7 @@ @ToString(callSuper = true) public class HistogramColumnDescription extends ColumnStatsCollector.ResultColumnStatistics { - public static record Entry(String label, long value) {}; + public record Entry(String label, long value) {}; private final List entries; private final Map extras; diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/NumberColumnStatsCollector.java b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/NumberColumnStatsCollector.java index e2f83d13be..f2c6ca82be 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/NumberColumnStatsCollector.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/NumberColumnStatsCollector.java @@ -10,7 +10,6 @@ import c10n.C10N; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import com.bakdata.conquery.models.types.ResultType; import com.google.common.collect.Range; import lombok.Getter; @@ -101,13 +100,7 @@ public void consume(Object value) { return; } - Number number = (Number) value; - - if (ResultType.Primitive.MONEY.equals(getType())) { - number = ResultPrinters.readMoney(getPrintSettings(), number); - } - - statistics.addValue(number.doubleValue()); + statistics.addValue(((Number) value).doubleValue()); } @Override diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ResultStatistics.java b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ResultStatistics.java index 891caae97e..45f0b1715d 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ResultStatistics.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/ResultStatistics.java @@ -18,6 +18,9 @@ import com.bakdata.conquery.models.query.SingleTableResult; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; +import com.bakdata.conquery.models.query.resultinfo.printers.JavaResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.models.types.SemanticType; @@ -34,13 +37,19 @@ public record ResultStatistics(int entities, int total, List statistics, Range dateRange) { @SneakyThrows @NotNull - public static ResultStatistics collectResultStatistics(SingleTableResult managedQuery, List resultInfos, Optional dateInfo, Optional dateIndex, PrintSettings printSettings, UniqueNamer uniqueNamer, ConqueryConfig conqueryConfig) { + public static ResultStatistics collectResultStatistics( + SingleTableResult managedQuery, + List resultInfos, + Optional dateInfo, + Optional dateIndex, + PrintSettings printSettings, + UniqueNamer uniqueNamer, + ConqueryConfig conqueryConfig, + PrinterFactory printerFactory) { //TODO pull inner executor service from ManagerNode - final ListeningExecutorService - executorService = - MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1)); + final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 1)); // Yes, we are actually iterating the result for every job. @@ -50,7 +59,7 @@ public static ResultStatistics collectResultStatistics(SingleTableResult managed final boolean containsDates = dateInfo.isPresent(); if (containsDates) { - futureSpan = executorService.submit(() -> calculateDateSpan(managedQuery, dateInfo, dateIndex.get())); + futureSpan = executorService.submit(() -> calculateDateSpan(managedQuery, dateInfo, dateIndex.get(), printSettings)); } else { futureSpan = Futures.immediateFuture(CDateRange.all().toSimpleRange()); @@ -59,12 +68,10 @@ public static ResultStatistics collectResultStatistics(SingleTableResult managed // Count result lines and entities (may differ in case of form or SecondaryIdQuery) final ListenableFuture futureLines = executorService.submit(() -> (int) managedQuery.resultRowCount()); - final ListenableFuture futureEntities = - executorService.submit(() -> (int) managedQuery.streamResults(OptionalLong.empty()).count()); + final ListenableFuture futureEntities = executorService.submit(() -> (int) managedQuery.streamResults(OptionalLong.empty()).count()); // compute ResultColumnStatistics for each column - final List> - futureDescriptions = + final List> futureDescriptions = IntStream.range(0, resultInfos.size()) // If the query doesn't contain dates, we can skip the dates-column. .filter(col -> !resultInfos.get(col).getSemantics().contains(new SemanticType.EventDateT()) || containsDates) @@ -72,15 +79,29 @@ public static ResultStatistics collectResultStatistics(SingleTableResult managed final StopWatch started = StopWatch.createStarted(); final ResultInfo info = resultInfos.get(col); + final Printer printer = info.createPrinter(printerFactory, printSettings); final ColumnStatsCollector statsCollector = - ColumnStatsCollector.getStatsCollector(uniqueNamer.getUniqueName(info), info.getDescription(), info.getType(), info.getPrinter(), printSettings, conqueryConfig.getFrontend()); + ColumnStatsCollector.getStatsCollector(uniqueNamer.getUniqueName(info, printSettings), + info.getDescription(), + info.getType(), + printSettings, + conqueryConfig.getFrontend() + ); log.trace("BEGIN stats collection for {}", info); managedQuery.streamResults(OptionalLong.empty()) .map(EntityResult::listResultLines) .flatMap(List::stream) - .forEach(line -> statsCollector.consume(line[col])); + .forEach(line -> { + final Object value = line[col]; + if (value == null) { + // Printers dont handle null + statsCollector.consume(null); + return; + } + statsCollector.consume(printer.apply(value)); + }); log.trace("DONE collecting values for {}, in {}", info, started); @@ -103,13 +124,13 @@ public static ResultStatistics collectResultStatistics(SingleTableResult managed return new ResultStatistics(entities, lines, descriptions, span); } - private static Range calculateDateSpan(SingleTableResult managedQuery, Optional dateInfo, int dateIndex) { + private static Range calculateDateSpan(SingleTableResult managedQuery, Optional dateInfo, int dateIndex, PrintSettings printSettings) { if (dateInfo.isEmpty()) { return CDateRange.all().toSimpleRange(); } final AtomicReference spanRef = new AtomicReference<>(null); - final Consumer dateAggregator = getDateSpanner(dateInfo.get(), dateIndex, spanRef); + final Consumer dateAggregator = getDateSpanner(dateInfo.get(), dateIndex, spanRef, printSettings); managedQuery.streamResults(OptionalLong.empty()).flatMap(EntityResult::streamValues).forEach(dateAggregator); @@ -125,28 +146,32 @@ private static Range calculateDateSpan(SingleTableResult managedQuery /** * If not dateInfo is given, don't try to span values. otherwise takes values from line at dateIndex, and handles them according to dateInfo. */ - private static Consumer getDateSpanner(ResultInfo dateInfo, int dateIndex, AtomicReference spanRef) { + private static Consumer getDateSpanner(ResultInfo dateInfo, int dateIndex, AtomicReference spanRef, PrintSettings printSettings) { final Consumer spanner = date -> spanRef.getAndAccumulate(date, (old, incoming) -> incoming.spanClosed(old)); - final BiConsumer> extractor = validityDateExtractor(dateInfo.getType()); + final JavaResultPrinters printers = new JavaResultPrinters(); + final BiConsumer> extractor = validityDateExtractor(dateInfo.getType(), printSettings, printers); return line -> extractor.accept(line[dateIndex], spanner); } - public static BiConsumer> validityDateExtractor(ResultType dateType) { + public static BiConsumer> validityDateExtractor(ResultType dateType, PrintSettings printSettings, JavaResultPrinters printers) { + if (dateType.equals(ResultType.Primitive.DATE_RANGE)) { - return (obj, con) -> con.accept(CDateRange.fromList((List) obj)); + final Printer printer = printers.getDateRangePrinter(printSettings); + return (obj, con) -> con.accept((CDateRange) printer.apply(obj)); } if (dateType.equals(ResultType.Primitive.DATE)) { - return (obj, con) -> con.accept(CDateRange.exactly((Integer) obj)); + final Printer printer = printers.getDatePrinter(printSettings); + return (obj, con) -> con.accept(CDateRange.exactly((LocalDate) printer.apply(obj))); } if (dateType instanceof ResultType.ListT listT) { - final BiConsumer> extractor = validityDateExtractor(listT.getElementType()); + final BiConsumer> extractor = validityDateExtractor(listT.getElementType(), printSettings, printers); return (obj, con) -> ((List) obj).forEach(date -> extractor.accept(date, con)); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/StringColumnStatsCollector.java b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/StringColumnStatsCollector.java index 19babdfcb5..c66d368b65 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/query/statistics/StringColumnStatsCollector.java +++ b/backend/src/main/java/com/bakdata/conquery/models/query/statistics/StringColumnStatsCollector.java @@ -8,7 +8,6 @@ import c10n.C10N; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.math3.stat.Frequency; @@ -19,15 +18,13 @@ public class StringColumnStatsCollector extends ColumnStatsCollector { private final Frequency frequencies = new Frequency(); private final long limit; - private final ResultPrinters.Printer printer; private int nulls = 0; - public StringColumnStatsCollector(String name, String label, String description, ResultPrinters.Printer printer, PrintSettings printSettings, long limit) { + public StringColumnStatsCollector(String name, String label, String description, PrintSettings printSettings, long limit) { super(name, label, description, printSettings); this.limit = limit; - this.printer = printer; } @Override @@ -38,7 +35,7 @@ public void consume(Object value) { } // In case there's a mapping, we need to map the value - final String printed = printer.print(value); + final String printed = (String) value; frequencies.addValue(printed); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java index 1eb1daa5fe..16fe976764 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/model/filter/NumberFilterConverter.java @@ -1,13 +1,10 @@ package com.bakdata.conquery.sql.conversion.model.filter; -import java.math.BigDecimal; import java.util.List; import com.bakdata.conquery.models.common.IRange; -import com.bakdata.conquery.models.common.Range; import com.bakdata.conquery.models.datasets.Column; import com.bakdata.conquery.models.datasets.concepts.filters.specific.NumberFilter; -import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConceptCteStep; import com.bakdata.conquery.sql.conversion.cqelement.concept.ConnectorSqlTables; import com.bakdata.conquery.sql.conversion.cqelement.concept.FilterContext; @@ -30,16 +27,12 @@ public SqlFilters convertToSqlFilter(NumberFilter filter, FilterContext rootSelect = new ExtractingSqlSelect<>(tables.getRootTable(), column.getName(), numberClass); Field eventFilterCtePredecessor = rootSelect.qualify(tables.getPredecessor(ConceptCteStep.EVENT_FILTER)).select(); - IRange filterValue = prepareFilterValue(column, filterContext.getValue()); + IRange filterValue = NumberFilter.readFilterValue(filterContext.getValue(), column.getType(), filter.getConfig()); NumberCondition condition = new NumberCondition(eventFilterCtePredecessor, filterValue); - ConnectorSqlSelects selects = ConnectorSqlSelects.builder() - .preprocessingSelects(List.of(rootSelect)) - .build(); + ConnectorSqlSelects selects = ConnectorSqlSelects.builder().preprocessingSelects(List.of(rootSelect)).build(); - WhereClauses whereClauses = WhereClauses.builder() - .eventFilter(condition) - .build(); + WhereClauses whereClauses = WhereClauses.builder().eventFilter(condition).build(); return new SqlFilters(selects, whereClauses); } @@ -50,24 +43,8 @@ public Condition convertForTableExport(NumberFilter filter, FilterContext String tableName = column.getTable().getName(); String columnName = column.getName(); Field field = DSL.field(DSL.name(tableName, columnName), Number.class); - return new NumberCondition(field, filterContext.getValue()).condition(); - } + IRange range = NumberFilter.readFilterValue(filterContext.getValue(), column.getType(), filter.getConfig()); - /** - * If there is a long range filter on a column of type MONEY, the filter value will represent a decimal with the point moved right 2 places right. - *

- * For example, the filter value {@code {min: 1000€, max: 2000€}} will be converted to {@code {min: 10,00€, max: 20,00€}} - */ - private static IRange prepareFilterValue(Column column, IRange filterValue) { - if (column.getType() != MajorTypeId.MONEY || !(filterValue instanceof Range.LongRange)) { - return filterValue; - } - Long min = (Long) filterValue.getMin(); - Long max = (Long) filterValue.getMax(); - return Range.LongRange.of( - BigDecimal.valueOf(min).movePointLeft(2), - BigDecimal.valueOf(max).movePointLeft(2) - ); + return new NumberCondition(field, range).condition(); } - } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/AbsoluteFormQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/AbsoluteFormQueryConverter.java index 573f2222b4..189a1748b6 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/AbsoluteFormQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/AbsoluteFormQueryConverter.java @@ -40,7 +40,7 @@ public ConversionContext convert(AbsoluteFormQuery form, ConversionContext conte FormType.ABSOLUTE, stratificationTable, form.getFeatures(), - form.getResultInfos(context.getSqlPrintSettings()), + form.getResultInfos(), context ); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java index 74f66d3e42..055bfcc262 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/ConceptQueryConverter.java @@ -46,7 +46,7 @@ public ConversionContext convert(ConceptQuery conceptQuery, ConversionContext co .build(); Select finalQuery = this.queryStepTransformer.toSelectQuery(finalStep); - return contextAfterConversion.withFinalQuery(new SqlQuery(finalQuery, conceptQuery.getResultInfos(context.getSqlPrintSettings()))); + return contextAfterConversion.withFinalQuery(new SqlQuery(finalQuery, conceptQuery.getResultInfos())); } private Selects getFinalSelects(ConceptQuery conceptQuery, Selects preFinalSelects, SqlFunctionProvider functionProvider) { diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/EntityDateQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/EntityDateQueryConverter.java index 917f49f8f3..457eebe740 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/EntityDateQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/EntityDateQueryConverter.java @@ -39,7 +39,7 @@ public ConversionContext convert(EntityDateQuery entityDateQuery, ConversionCont FormType.ENTITY_DATE, stratificationTable, entityDateQuery.getFeatures(), - entityDateQuery.getResultInfos(context.getSqlPrintSettings()), + entityDateQuery.getResultInfos(), context ); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/RelativFormQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/RelativFormQueryConverter.java index b0062afbdc..544d1e0548 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/RelativFormQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/RelativFormQueryConverter.java @@ -29,7 +29,7 @@ public ConversionContext convert(RelativeFormQuery form, ConversionContext conte FormType.RELATIVE, stratificationTable, form.getFeatures(), - form.getResultInfos(context.getSqlPrintSettings()), + form.getResultInfos(), context ); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/SecondaryIdQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/SecondaryIdQueryConverter.java index 34c3511f63..e5d9ee6197 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/SecondaryIdQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/SecondaryIdQueryConverter.java @@ -22,7 +22,7 @@ public ConversionContext convert(SecondaryIdQuery query, ConversionContext conte ); Preconditions.checkArgument(withConvertedQuery.getFinalQuery() != null, "The SecondaryIdQuery's query should be converted by now."); - SqlQuery secondaryIdSqlQuery = withConvertedQuery.getFinalQuery().overwriteResultInfos(query.getResultInfos(context.getSqlPrintSettings())); + SqlQuery secondaryIdSqlQuery = withConvertedQuery.getFinalQuery().overwriteResultInfos(query.getResultInfos()); return withConvertedQuery.withFinalQuery(secondaryIdSqlQuery); } diff --git a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java index 37489e79d0..a519d5e8a1 100644 --- a/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java +++ b/backend/src/main/java/com/bakdata/conquery/sql/conversion/query/TableExportQueryConverter.java @@ -70,7 +70,7 @@ public ConversionContext convert(TableExportQuery tableExportQuery, ConversionCo ); Select selectQuery = queryStepTransformer.toSelectQuery(unionedTables); - return context.withFinalQuery(new SqlQuery(selectQuery, tableExportQuery.getResultInfos(context.getSqlPrintSettings()))); + return context.withFinalQuery(new SqlQuery(selectQuery, tableExportQuery.getResultInfos())); } /** diff --git a/backend/src/test/java/com/bakdata/conquery/api/StoredQueriesProcessorTest.java b/backend/src/test/java/com/bakdata/conquery/api/StoredQueriesProcessorTest.java index 1793c36229..f233059782 100644 --- a/backend/src/test/java/com/bakdata/conquery/api/StoredQueriesProcessorTest.java +++ b/backend/src/test/java/com/bakdata/conquery/api/StoredQueriesProcessorTest.java @@ -11,8 +11,6 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -import jakarta.validation.Validator; -import jakarta.ws.rs.core.UriBuilder; import com.bakdata.conquery.apiv1.QueryProcessor; import com.bakdata.conquery.apiv1.execution.ExecutionStatus; @@ -51,7 +49,6 @@ import com.bakdata.conquery.models.index.IndexService; import com.bakdata.conquery.models.query.DistributedExecutionManager; import com.bakdata.conquery.models.query.ManagedQuery; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.worker.DatasetRegistry; import com.bakdata.conquery.models.worker.DistributedNamespace; @@ -59,6 +56,8 @@ import com.google.common.collect.ImmutableList; import io.dropwizard.core.setup.Environment; import io.dropwizard.jersey.validation.Validators; +import jakarta.validation.Validator; +import jakarta.ws.rs.core.UriBuilder; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -232,7 +231,7 @@ private static ManagedQuery mockManagedQuery(Query queryDescription, User user, } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { // With method is mocked because the ExcelResultProvider needs some info to check dimensions, // but actually resolving the query here requires much more setup return Collections.emptyList(); @@ -254,7 +253,7 @@ private static ExecutionStatus makeState(ManagedExecutionId id, User owner, User } @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { return Collections.emptyList(); } }; diff --git a/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java b/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java index d6643ae4bb..6225b7ef06 100644 --- a/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java +++ b/backend/src/test/java/com/bakdata/conquery/execution/DefaultSqlCDateSetParserTest.java @@ -6,7 +6,7 @@ import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.query.PrintSettings; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; +import com.bakdata.conquery.models.query.resultinfo.printers.StringResultPrinters; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.sql.execution.DefaultSqlCDateSetParser; import org.junit.jupiter.api.Assertions; @@ -17,6 +17,7 @@ class DefaultSqlCDateSetParserTest { private static final DefaultSqlCDateSetParser parser = new DefaultSqlCDateSetParser(); + private static final StringResultPrinters csvResultPrinters = new StringResultPrinters(); private static final ConqueryConfig CONFIG = new ConqueryConfig(); private static final PrintSettings PLAIN = new PrintSettings(false, Locale.ENGLISH, null, CONFIG, null, null); @@ -24,7 +25,7 @@ class DefaultSqlCDateSetParserTest { @MethodSource("testToEpochDayRangeListProvider") public void testToEpochDayRangeList(String input, String expected, String message) { List> epochDayRangeList = parser.toEpochDayRangeList(input); - String actual = ResultPrinters.printerFor(new ResultType.ListT(ResultType.Primitive.DATE_RANGE), PLAIN).print(epochDayRangeList); + final String actual = (String) csvResultPrinters.>>printerFor(new ResultType.ListT<>(ResultType.Primitive.DATE_RANGE), PLAIN).apply(epochDayRangeList); Assertions.assertEquals(expected, actual, message); } diff --git a/backend/src/test/java/com/bakdata/conquery/integration/common/IntegrationUtils.java b/backend/src/test/java/com/bakdata/conquery/integration/common/IntegrationUtils.java index 248929d32b..552299152c 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/common/IntegrationUtils.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/common/IntegrationUtils.java @@ -6,6 +6,7 @@ import java.net.URI; import java.util.List; import java.util.Map; + import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.GenericType; import jakarta.ws.rs.core.MediaType; @@ -28,6 +29,9 @@ import com.bakdata.conquery.resources.hierarchies.HierarchyHelper; import com.bakdata.conquery.util.support.StandaloneSupport; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; @@ -82,8 +86,9 @@ public static ManagedExecutionId assertQueryResult(StandaloneSupport conquery, O .post(Entity.entity(query, MediaType.APPLICATION_JSON_TYPE)); - assertThat(response.getStatusInfo().getStatusCode()).as("Result of %s", postQueryURI) - .isEqualTo(expectedResponseCode); + assertThat(response.getStatusInfo().getStatusCode()) + .as(() -> response.readEntity(String.class)) + .isEqualTo(expectedResponseCode); if (expectedState == ExecutionState.FAILED && !response.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)) { return null; diff --git a/backend/src/test/java/com/bakdata/conquery/integration/json/AbstractQueryEngineTest.java b/backend/src/test/java/com/bakdata/conquery/integration/json/AbstractQueryEngineTest.java index c80ac829cf..a5bf248eab 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/json/AbstractQueryEngineTest.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/json/AbstractQueryEngineTest.java @@ -20,7 +20,6 @@ import com.bakdata.conquery.models.execution.ManagedExecution; import com.bakdata.conquery.models.identifiable.ids.specific.ManagedExecutionId; import com.bakdata.conquery.models.query.ManagedQuery; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.SingleTableResult; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.results.EntityResult; @@ -56,10 +55,7 @@ public void executeTest(StandaloneSupport standaloneSupport) throws IOException final ManagedExecution execution = standaloneSupport.getMetaStorage().getExecution(executionId); SingleTableResult executionResult = (SingleTableResult) execution; - //check result info size - PrintSettings printSettings = new PrintSettings(true, Locale.ROOT, standaloneSupport.getNamespace(), standaloneSupport.getConfig(), null, null); - - List resultInfos = executionResult.getResultInfos(printSettings); + List resultInfos = executionResult.getResultInfos(); assertThat(executionResult.streamResults(OptionalLong.empty()).flatMap(EntityResult::streamValues)) .as("Should have same size as result infos") diff --git a/backend/src/test/java/com/bakdata/conquery/integration/json/FormTest.java b/backend/src/test/java/com/bakdata/conquery/integration/json/FormTest.java index e815960212..eb5d2edcbe 100644 --- a/backend/src/test/java/com/bakdata/conquery/integration/json/FormTest.java +++ b/backend/src/test/java/com/bakdata/conquery/integration/json/FormTest.java @@ -16,12 +16,15 @@ import jakarta.validation.constraints.NotNull; import com.bakdata.conquery.apiv1.forms.Form; +import com.bakdata.conquery.integration.common.LoadingUtil; import com.bakdata.conquery.integration.common.RequiredData; import com.bakdata.conquery.integration.common.ResourceFile; import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.io.result.csv.CsvRenderer; import com.bakdata.conquery.models.auth.entities.User; import com.bakdata.conquery.models.config.ConqueryConfig; +import com.bakdata.conquery.models.datasets.Dataset; +import com.bakdata.conquery.models.datasets.concepts.Concept; import com.bakdata.conquery.models.exceptions.JSONException; import com.bakdata.conquery.models.execution.ExecutionState; import com.bakdata.conquery.models.forms.managed.ManagedForm; @@ -74,6 +77,25 @@ public class FormTest extends ConqueryTestSpec { @JsonIgnore private Form form; + private static void importConcepts(StandaloneSupport support, ArrayNode rawConcepts) throws JSONException, IOException { + if (rawConcepts == null) { + return; + } + + Dataset dataset = support.getDataset(); + + List> concepts = parseSubTreeList( + support, + rawConcepts, + Concept.class, + c -> c.setDataset(support.getDataset()) + ); + + for (Concept concept : concepts) { + LoadingUtil.uploadConcept(support, dataset, concept); + } + } + @ValidationMethod(message = "Form test defines no concepts. Neither explicit nor automatic concepts") public boolean isWithConcepts() { return rawConcepts != null || content.isAutoConcept(); @@ -86,6 +108,10 @@ public void importRequiredData(StandaloneSupport support) throws Exception { form = parseForm(support); } + private Form parseForm(StandaloneSupport support) throws JSONException, IOException { + return parseSubTree(support, rawForm, Form.class); + } + @Override public void executeTest(StandaloneSupport support) throws Exception { Namespace namespace = support.getNamespace(); @@ -99,8 +125,9 @@ public void executeTest(StandaloneSupport support) throws Exception { ManagedInternalForm managedForm = (ManagedInternalForm) executionManager .runQuery(namespace, form, support.getTestUser(), support.getConfig(), false); - ExecutionState executionState = namespace.getExecutionManager().awaitDone(managedForm, 10, TimeUnit.MINUTES); - if (executionState != ExecutionState.DONE) { + namespace.getExecutionManager().awaitDone(managedForm, 1, TimeUnit.MINUTES); + + if (managedForm.getState() != ExecutionState.DONE) { if (managedForm.getState() == ExecutionState.FAILED) { fail(getLabel() + " Query failed"); } @@ -133,77 +160,72 @@ private void checkResults(StandaloneSupport standaloneSupport, ManagedInternalFo } /** - * Checks result of subqueries instead of form result. + * The form produces only one result, so the result is directly requested. * - * @see FormTest#checkSingleResult(ManagedForm, ConqueryConfig, PrintSettings) + * @see FormTest#checkMultipleResult(Map, ConqueryConfig, PrintSettings) */ - private void checkMultipleResult(Map> managedMapping, ConqueryConfig config, PrintSettings printSettings) throws IOException { - for (Map.Entry> managed : managedMapping.entrySet()) { - List resultInfos = managed.getValue().get(0).getResultInfos(printSettings); - log.info("{} CSV TESTING: {}", getLabel(), managed.getKey()); + private void checkSingleResult(F managedForm, ConqueryConfig config, PrintSettings printSettings) + throws IOException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); + try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { final CsvWriter writer = config.getCsv().createWriter(output); - - CsvRenderer renderer = new CsvRenderer(writer, printSettings); + final CsvRenderer renderer = new CsvRenderer(writer, printSettings); renderer.toCSV( - config.getIdColumns().getIdResultInfos(printSettings), - resultInfos, - managed.getValue() - .stream() - .flatMap(managedQuery -> managedQuery.streamResults(OptionalLong.empty())) + config.getIdColumns().getIdResultInfos(), + managedForm.getResultInfos(), + managedForm.streamResults(OptionalLong.empty()), printSettings ); writer.close(); - output.close(); assertThat(In.stream(new ByteArrayInputStream(output.toByteArray())).withUTF8().readLines()) - .as("Checking result " + managed.getKey()) + .as("Checking result " + managedForm.getLabelWithoutAutoLabelSuffix()) .containsExactlyInAnyOrderElementsOf( - In.stream(expectedCsv.get(managed.getKey()).stream()) + In.stream(expectedCsv.values().iterator().next().stream()) .withUTF8() .readLines() ); } + + } /** - * The form produces only one result, so the result is directly requested. + * Checks result of subqueries instead of form result. * - * @see FormTest#checkMultipleResult(Map, ConqueryConfig, PrintSettings) + * @see FormTest#checkSingleResult(ManagedForm, ConqueryConfig, PrintSettings) */ - private & SingleTableResult> void checkSingleResult(F managedForm, ConqueryConfig config, PrintSettings printSettings) - throws IOException { + private void checkMultipleResult(Map> managedMapping, ConqueryConfig config, PrintSettings printSettings) throws IOException { + for (Map.Entry> managed : managedMapping.entrySet()) { + List resultInfos = managed.getValue().get(0).getResultInfos(); + log.info("{} CSV TESTING: {}", getLabel(), managed.getKey()); + ByteArrayOutputStream output = new ByteArrayOutputStream(); - try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { final CsvWriter writer = config.getCsv().createWriter(output); - final CsvRenderer renderer = new CsvRenderer(writer, printSettings); + + CsvRenderer renderer = new CsvRenderer(writer, printSettings); renderer.toCSV( - config.getIdColumns().getIdResultInfos(printSettings), - managedForm.getResultInfos(printSettings), - managedForm.streamResults(OptionalLong.empty()) + config.getIdColumns().getIdResultInfos(), + resultInfos, + managed.getValue() + .stream() + .flatMap(managedQuery -> managedQuery.streamResults(OptionalLong.empty())), printSettings ); writer.close(); + output.close(); assertThat(In.stream(new ByteArrayInputStream(output.toByteArray())).withUTF8().readLines()) - .as("Checking result " + managedForm.getLabelWithoutAutoLabelSuffix()) + .as("Checking result " + managed.getKey()) .containsExactlyInAnyOrderElementsOf( - In.stream(expectedCsv.values().iterator().next().stream()) + In.stream(expectedCsv.get(managed.getKey()).stream()) .withUTF8() .readLines() ); } - - - } - - - private Form parseForm(StandaloneSupport support) throws JSONException, IOException { - return parseSubTree(support, rawForm, Form.class); } } diff --git a/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java b/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java index b2892e0fc4..66ab1a544e 100644 --- a/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java +++ b/backend/src/test/java/com/bakdata/conquery/io/result/ResultTestUtil.java @@ -1,33 +1,26 @@ package com.bakdata.conquery.io.result; -import static org.mockito.Mockito.mock; - +import java.math.BigDecimal; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.OptionalLong; -import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.bakdata.conquery.apiv1.query.Query; import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; import com.bakdata.conquery.models.auth.entities.User; -import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.datasets.Column; import com.bakdata.conquery.models.datasets.Dataset; import com.bakdata.conquery.models.datasets.concepts.select.Select; import com.bakdata.conquery.models.datasets.concepts.tree.TreeConcept; import com.bakdata.conquery.models.events.Bucket; import com.bakdata.conquery.models.query.ManagedQuery; -import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.QueryExecutionContext; import com.bakdata.conquery.models.query.entity.Entity; import com.bakdata.conquery.models.query.queryplan.aggregators.Aggregator; import com.bakdata.conquery.models.query.resultinfo.ExternalResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.query.results.MultilineEntityResult; import com.bakdata.conquery.models.query.results.SinglelineEntityResult; @@ -41,33 +34,32 @@ @UtilityClass public class ResultTestUtil { - - private static TreeConcept concept; + public static final User OWNER = new User("user", "User", null); + public static final Dataset DATASET = new Dataset("dataset"); + private static final TreeConcept CONCEPT; static { - concept = new TreeConcept(); - concept.setName("concept"); - concept.setDataset(new Dataset("dataset")); + CONCEPT = new TreeConcept(); + CONCEPT.setName("concept"); + CONCEPT.setDataset(DATASET); } - private static final PrintSettings - PRINT_SETTINGS = - new PrintSettings(false, Locale.ROOT, null, new ConqueryConfig(), null, (selectInfo) -> selectInfo.getSelect().getLabel()); - - public static List - ID_FIELDS = - Stream.of("id1", "id2") - .map(name -> new ExternalResultInfo(name, ResultType.Primitive.STRING, "", new ResultPrinters.StringPrinter(), Set.of(new SemanticType.IdT("ID")), PRINT_SETTINGS)) - .collect(Collectors.toList()); + public static List getIdFields() { + return Stream.of("id1", "id2").map(name -> { + ExternalResultInfo info = new ExternalResultInfo(name, ResultType.Primitive.STRING); + info.addSemantics(new SemanticType.IdT("ID")); + return info; + }).collect(Collectors.toList()); + } @NotNull public static ManagedQuery getTestQuery() { - return new ManagedQuery(mock(Query.class), mock(User.class), new Dataset(ResultTestUtil.class.getSimpleName()), null, null) { + return new ManagedQuery(null, OWNER, DATASET, null, null) { @Override - public List getResultInfos(PrintSettings printSettings) { + public List getResultInfos() { return getResultTypes().stream() - .map(resultType -> new TypedSelectDummy(resultType)) - .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet(), PRINT_SETTINGS)) + .map(TypedSelectDummy::new) + .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet())) .collect(Collectors.toList()); } @@ -80,12 +72,55 @@ public Stream streamResults(OptionalLong maybeLimit) { @NotNull public static List getResultTypes() { - return List.of(ResultType.Primitive.BOOLEAN, ResultType.Primitive.INTEGER, ResultType.Primitive.NUMERIC, ResultType.Primitive.DATE, ResultType.Primitive.DATE_RANGE, ResultType.Primitive.STRING, ResultType.Primitive.MONEY, new ResultType.ListT(ResultType.Primitive.BOOLEAN), new ResultType.ListT(ResultType.Primitive.DATE_RANGE), new ResultType.ListT(ResultType.Primitive.STRING)); + return List.of(ResultType.Primitive.BOOLEAN, + ResultType.Primitive.INTEGER, + ResultType.Primitive.NUMERIC, + ResultType.Primitive.DATE, + ResultType.Primitive.DATE_RANGE, + ResultType.Primitive.STRING, + ResultType.Primitive.MONEY, + new ResultType.ListT(ResultType.Primitive.BOOLEAN), + new ResultType.ListT(ResultType.Primitive.DATE_RANGE), + new ResultType.ListT(ResultType.Primitive.STRING) + ); } @NotNull public static List getTestEntityResults() { - return List.of(new SinglelineEntityResult("1", new Object[]{Boolean.TRUE, 2345634, 123423.34, 5646, List.of(345, 534), "test_string", 4521, List.of(true, false), List.of(List.of(345, 534), List.of(1, 2)), List.of("fizz", "buzz")}), new SinglelineEntityResult("2", new Object[]{Boolean.FALSE, null, null, null, null, null, null, List.of(), List.of(List.of(1234, Integer.MAX_VALUE)), List.of()}), new SinglelineEntityResult("2", new Object[]{Boolean.TRUE, null, null, null, null, null, null, List.of(false, false), null, null}), new MultilineEntityResult("3", List.of(new Object[]{Boolean.FALSE, null, null, null, null, null, null, List.of(false), null, null}, new Object[]{Boolean.TRUE, null, null, null, null, null, null, null, null, null}, new Object[]{Boolean.TRUE, null, null, null, null, null, 4, List.of(true, false, true, false), null, null}))); + return List.of(new SinglelineEntityResult("1", new Object[]{ + Boolean.TRUE, + 2345634, + 123423.34, + 5646, + List.of(345, 534), + "test_string", + new BigDecimal("45.21"), + List.of(true, false), + List.of(List.of(345, 534), List.of(1, 2)), + List.of("fizz", "buzz") + }), + new SinglelineEntityResult("2", new Object[]{ + Boolean.FALSE, null, null, null, null, null, null, List.of(), List.of(List.of(1234, Integer.MAX_VALUE)), List.of() + }), + new SinglelineEntityResult("2", new Object[]{Boolean.TRUE, null, null, null, null, null, null, List.of(false, false), null, null}), + new MultilineEntityResult("3", + List.of(new Object[]{Boolean.FALSE, null, null, null, null, null, null, List.of(false), null, null}, + new Object[]{Boolean.TRUE, null, null, null, null, null, null, null, null, null}, + new Object[]{ + Boolean.TRUE, + null, + null, + null, + null, + null, + new BigDecimal("4.00"), + List.of(true, false, true, false), + null, + null + } + ) + ) + ); } public static class TypedSelectDummy extends Select { @@ -95,7 +130,7 @@ public static class TypedSelectDummy extends Select { public TypedSelectDummy(ResultType resultType) { setLabel(resultType.toString()); - setHolder(concept); + setHolder(CONCEPT); this.resultType = resultType; } diff --git a/backend/src/test/java/com/bakdata/conquery/io/result/arrow/ArrowResultGenerationTest.java b/backend/src/test/java/com/bakdata/conquery/io/result/arrow/ArrowResultGenerationTest.java index b7640e817b..497fa526b4 100644 --- a/backend/src/test/java/com/bakdata/conquery/io/result/arrow/ArrowResultGenerationTest.java +++ b/backend/src/test/java/com/bakdata/conquery/io/result/arrow/ArrowResultGenerationTest.java @@ -10,6 +10,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -22,7 +23,6 @@ import java.util.stream.Stream; import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; -import com.bakdata.conquery.io.result.ResultTestUtil; import com.bakdata.conquery.models.common.CDate; import com.bakdata.conquery.models.config.ArrowConfig; import com.bakdata.conquery.models.config.ConqueryConfig; @@ -33,9 +33,9 @@ import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; import com.bakdata.conquery.models.query.resultinfo.UniqueNamer; +import com.bakdata.conquery.models.query.resultinfo.printers.ArrowResultPrinters; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.types.ResultType; -import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.arrow.vector.FieldVector; import org.apache.arrow.vector.VectorSchemaRoot; @@ -53,202 +53,212 @@ @Slf4j public class ArrowResultGenerationTest { - private static final int BATCH_SIZE = 2; - public static final ConqueryConfig CONFIG = new ConqueryConfig(); - private static final PrintSettings - PRINT_SETTINGS = - new PrintSettings(false, Locale.ROOT, null, CONFIG, null, (selectInfo) -> selectInfo.getSelect().getLabel()); + public static final ConqueryConfig CONFIG = new ConqueryConfig(); + private static final int BATCH_SIZE = 2; + private static final PrintSettings PRINT_SETTINGS = new PrintSettings(false, Locale.ROOT, null, CONFIG, null, (selectInfo) -> selectInfo.getSelect().getLabel()); + public static String readTSV(InputStream inputStream) throws IOException { + StringJoiner stringJoiner = new StringJoiner("\n"); + try (ArrowStreamReader arrowReader = new ArrowStreamReader(inputStream, ROOT_ALLOCATOR)) { + log.info("Reading the produced arrow data."); + VectorSchemaRoot readRoot = arrowReader.getVectorSchemaRoot(); + stringJoiner.add(readRoot.getSchema().getFields().stream().map(Field::getName).collect(Collectors.joining("\t"))); + readRoot.setRowCount(BATCH_SIZE); + while (arrowReader.loadNextBatch()) { + List vectors = readRoot.getFieldVectors(); + + for (int rowI = 0; rowI < readRoot.getRowCount(); rowI++) { + final int currentRow = rowI; + stringJoiner.add(vectors.stream() + .map(vec -> vec.getObject(currentRow)) + .map(ArrowResultGenerationTest::getPrintValue) + .collect(Collectors.joining("\t"))); + } + } + } + return stringJoiner.toString(); + } + + public static String generateExpectedTSV(List results, List resultInfos) { + String expected = + results.stream() + .map(EntityResult.class::cast) + .map(res -> { + StringJoiner lineJoiner = new StringJoiner("\n"); + + for (Object[] line : res.listResultLines()) { + StringJoiner valueJoiner = new StringJoiner("\t"); + + valueJoiner.add(String.valueOf(res.getEntityId())); + valueJoiner.add(String.valueOf(res.getEntityId())); + + for (int lIdx = 0; lIdx < line.length; lIdx++) { + Object val = line[lIdx]; + ResultInfo info = resultInfos.get(lIdx); + + valueJoiner.add(getPrintValue(val, info.getType())); + } + + lineJoiner.add(valueJoiner.toString()); + } + return lineJoiner.toString(); + }).collect(Collectors.joining("\n")); + + return Stream.concat( + // Id column headers + getIdFields().stream().map(i -> i.defaultColumnName(PRINT_SETTINGS)), + // result column headers + getResultTypes().stream().map(ResultType::typeInfo) + ) + .collect(Collectors.joining("\t")) + + "\n" + + expected; + } + + private static String getPrintValue(Object obj, ResultType type) { + if (obj == null) { + return "null"; + } + if (type.equals(ResultType.Primitive.MONEY)) { + return Integer.toString(((BigDecimal) obj).unscaledValue().intValueExact()); + } + if (type.equals(ResultType.Primitive.DATE_RANGE)) { + // Special case for daterange in this test because it uses a StructVector, we rebuild the structural information + List dr = (List) obj; + StringBuilder sb = new StringBuilder(); + sb.append("{"); + final int min = (int) dr.get(0); + final int max = (int) dr.get(1); + // Handle cases where one of the limits is infinity + if (!CDate.isNegativeInfinity(min)) { + sb.append("\"min\":").append(min); + } + if (!CDate.isNegativeInfinity(min) && !CDate.isPositiveInfinity(max)) { + sb.append(","); + } + if (!CDate.isPositiveInfinity(max)) { + sb.append("\"max\":").append(max); + } + sb.append("}"); + return sb.toString(); + } + if (obj instanceof Collection) { + Collection col = (Collection) obj; + // Workaround: Arrow deserializes lists as a JsonStringArrayList which has a JSON String method + ResultType elemType = ((ResultType.ListT) type).getElementType(); + return col.stream().map(v -> getPrintValue(v, elemType)).collect(Collectors.joining(",", "[", "]")); + } + return obj.toString(); + } + + private static String getPrintValue(Object obj) { + if (obj instanceof JsonStringArrayList) { + // Workaround: Arrow deserializes lists as a JsonStringArrayList which has a JSON String method + return new ArrayList<>((JsonStringArrayList) obj).stream().map(ArrowResultGenerationTest::getPrintValue).collect(Collectors.joining(",", "[", "]")); + } + return Objects.toString(obj); + } @Test - void generateFieldsIdMapping() { + void generateFieldsIdMapping() { final UniqueNamer uniqueNamer = new UniqueNamer(PRINT_SETTINGS); - List fields = generateFields(ResultTestUtil.ID_FIELDS, uniqueNamer); + List fields = generateFields(getIdFields(), uniqueNamer, PRINT_SETTINGS); - assertThat(fields).containsExactlyElementsOf( - List.of( - new Field("id1", FieldType.nullable(new ArrowType.Utf8()), null), - new Field("id2", FieldType.nullable(new ArrowType.Utf8()), null))); + assertThat(fields).containsExactlyElementsOf( + List.of(new Field("id1", FieldType.nullable(new ArrowType.Utf8()), null), + new Field("id2", FieldType.nullable(new ArrowType.Utf8()), null) + )); - } + } - @Test - void generateFieldsValue() { + @Test + void generateFieldsValue() { final UniqueNamer uniqueNamer = new UniqueNamer(PRINT_SETTINGS); + List resultInfos = getResultTypes().stream() + .map(TypedSelectDummy::new) + .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet())) + .collect(Collectors.toList()); - List resultInfos = getResultTypes().stream().map(TypedSelectDummy::new) - .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet(), PRINT_SETTINGS)).collect(Collectors.toList()); - - List fields = generateFields( - resultInfos, - // Custom column namer so we don't require a dataset registry - uniqueNamer + List fields = generateFields(resultInfos, + // Custom column namer so we don't require a dataset registry + uniqueNamer, PRINT_SETTINGS ); - assertThat(fields).containsExactlyElementsOf( - List.of( - new Field("BOOLEAN", FieldType.nullable(ArrowType.Bool.INSTANCE), null), - new Field("INTEGER", FieldType.nullable(new ArrowType.Int(32, true)), null), - new Field("NUMERIC", FieldType.nullable(new ArrowType.FloatingPoint(FloatingPointPrecision.DOUBLE)), null), - new Field("DATE", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null), - new Field("DATE_RANGE", - FieldType.nullable(ArrowType.Struct.INSTANCE), - List.of( - new Field("min", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null), - new Field("max", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null) - )), - new Field("STRING", FieldType.nullable(new ArrowType.Utf8()), null), - new Field("MONEY", FieldType.nullable(new ArrowType.Int(32, true)), null), - new Field("LIST[BOOLEAN]", FieldType.nullable(ArrowType.List.INSTANCE), List.of(new Field("LIST[BOOLEAN]", FieldType.nullable(ArrowType.Bool.INSTANCE), null))), - new Field("LIST[DATE_RANGE]", FieldType.nullable(ArrowType.List.INSTANCE), List.of(new Field("LIST[DATE_RANGE]", - FieldType.nullable(ArrowType.Struct.INSTANCE), - List.of( - new Field("min", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null), - new Field("max", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null) - )))), - new Field("LIST[STRING]", FieldType.nullable(ArrowType.List.INSTANCE), List.of(new Field("LIST[STRING]", FieldType.nullable(new ArrowType.Utf8()), null))) - ) - ); - - } - - @Test - void writeAndRead() throws IOException { - - // Initialize internationalization - I18n.init(); - - // Prepare every input data - PrintSettings printSettings = new PrintSettings( - false, - Locale.ROOT, - null, - CONFIG, - (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), - (selectInfo) -> selectInfo.getSelect().getLabel()); - // The Shard nodes send Object[] but since Jackson is used for deserialization, nested collections are always a list because they are not further specialized - List results = getTestEntityResults(); - - ManagedQuery mquery = getTestQuery(); - - // First we write to the buffer, than we read from it and parse it as TSV - ByteArrayOutputStream output = new ByteArrayOutputStream(); - - renderToStream( - (root) -> new ArrowStreamWriter(root, new DictionaryProvider.MapDictionaryProvider(), output), - printSettings, - new ArrowConfig(BATCH_SIZE), - ResultTestUtil.ID_FIELDS, - mquery.getResultInfos(printSettings), - mquery.streamResults(OptionalLong.empty()) + assertThat(fields).containsExactlyElementsOf( + List.of(new Field("BOOLEAN", FieldType.nullable(ArrowType.Bool.INSTANCE), null), + new Field("INTEGER", FieldType.nullable(new ArrowType.Int(32, true)), null), + new Field("NUMERIC", FieldType.nullable(new ArrowType.FloatingPoint(FloatingPointPrecision.DOUBLE)), null), + new Field("DATE", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null), + new Field("DATE_RANGE", + FieldType.nullable(ArrowType.Struct.INSTANCE), + List.of(new Field("min", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null), + new Field("max", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null) + ) + ), + new Field("STRING", FieldType.nullable(new ArrowType.Utf8()), null), + new Field("MONEY", FieldType.nullable(new ArrowType.Int(32, true)), null), + new Field("LIST[BOOLEAN]", + FieldType.nullable(ArrowType.List.INSTANCE), + List.of(new Field("LIST[BOOLEAN]", FieldType.nullable(ArrowType.Bool.INSTANCE), null)) + ), + new Field("LIST[DATE_RANGE]", + FieldType.nullable(ArrowType.List.INSTANCE), + List.of(new Field("LIST[DATE_RANGE]", + FieldType.nullable(ArrowType.Struct.INSTANCE), + List.of(new Field("min", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null), + new Field("max", FieldType.nullable(new ArrowType.Date(DateUnit.DAY)), null) + ) + )) + ), + new Field("LIST[STRING]", + FieldType.nullable(ArrowType.List.INSTANCE), + List.of(new Field("LIST[STRING]", FieldType.nullable(new ArrowType.Utf8()), null)) + ) + )); + + } + + @Test + void writeAndRead() throws IOException { + + // Initialize internationalization + I18n.init(); + + // Prepare every input data + PrintSettings printSettings = new PrintSettings(false, + Locale.ROOT, + null, + CONFIG, + (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), + (selectInfo) -> selectInfo.getSelect().getLabel() ); + // The Shard nodes send Object[] but since Jackson is used for deserialization, nested collections are always a list because they are not further specialized + List results = getTestEntityResults(); - InputStream inputStream = new ByteArrayInputStream(output.toByteArray()); + ManagedQuery mquery = getTestQuery(); - String computed = readTSV(inputStream); + // First we write to the buffer, than we read from it and parse it as TSV + ByteArrayOutputStream output = new ByteArrayOutputStream(); - assertThat(computed).isNotBlank(); - assertThat(computed).isEqualTo(generateExpectedTSV(results, mquery.getResultInfos(printSettings), printSettings)); + renderToStream((root) -> new ArrowStreamWriter(root, new DictionaryProvider.MapDictionaryProvider(), output), + printSettings, + new ArrowConfig(BATCH_SIZE), + getIdFields(), + mquery.getResultInfos(), + mquery.streamResults(OptionalLong.empty()), + new ArrowResultPrinters() + ); - } + InputStream inputStream = new ByteArrayInputStream(output.toByteArray()); - public static String readTSV(InputStream inputStream) throws IOException { - StringJoiner stringJoiner = new StringJoiner("\n"); - try (ArrowStreamReader arrowReader = new ArrowStreamReader(inputStream, ROOT_ALLOCATOR)) { - log.info("Reading the produced arrow data."); - VectorSchemaRoot readRoot = arrowReader.getVectorSchemaRoot(); - stringJoiner.add(readRoot.getSchema().getFields().stream().map(Field::getName).collect(Collectors.joining("\t"))); - readRoot.setRowCount(BATCH_SIZE); - while (arrowReader.loadNextBatch()) { - List vectors = readRoot.getFieldVectors(); + String computed = readTSV(inputStream); - for (int rowI = 0; rowI < readRoot.getRowCount(); rowI++) { - final int currentRow = rowI; - stringJoiner.add( - vectors.stream() - .map(vec -> vec.getObject(currentRow)) - .map(ArrowResultGenerationTest::getPrintValue) - .collect(Collectors.joining("\t"))); - } - } - } - return stringJoiner.toString(); - } - - public static String generateExpectedTSV(List results, List resultInfos, PrintSettings settings) { - String expected = results.stream() - .map(EntityResult.class::cast) - .map(res -> { - StringJoiner lineJoiner = new StringJoiner("\n"); - - for (Object[] line : res.listResultLines()) { - StringJoiner valueJoiner = new StringJoiner("\t"); - valueJoiner.add(String.valueOf(res.getEntityId())); - valueJoiner.add(String.valueOf(res.getEntityId())); - for (int lIdx = 0; lIdx < line.length; lIdx++) { - Object val = line[lIdx]; - ResultInfo info = resultInfos.get(lIdx); - valueJoiner.add(getPrintValue(val, info.getType(), settings)); - } - lineJoiner.add(valueJoiner.toString()); - } - return lineJoiner.toString(); - }) - .collect(Collectors.joining("\n")); + assertThat(computed).isNotBlank(); + assertThat(computed).isEqualTo(generateExpectedTSV(results, mquery.getResultInfos())); - return Stream.concat( - // Id column headers - ResultTestUtil.ID_FIELDS.stream().map(i -> i.defaultColumnName()), - // result column headers - getResultTypes().stream().map(ResultType::typeInfo) - ).collect(Collectors.joining("\t")) - + "\n" + expected; - } - - private static String getPrintValue(Object obj, ResultType type, PrintSettings settings) { - if (obj == null) { - return "null"; - } - if (type.equals(ResultType.Primitive.DATE_RANGE)) { - // Special case for daterange in this test because it uses a StructVector, we rebuild the structural information - List dr = (List) obj; - StringBuilder sb = new StringBuilder(); - sb.append("{"); - final int min = (int) dr.get(0); - final int max = (int) dr.get(1); - // Handle cases where one of the limits is infinity - if (!CDate.isNegativeInfinity(min)) { - sb.append("\"min\":").append(min); - } - if (!CDate.isNegativeInfinity(min) && !CDate.isPositiveInfinity(max)) { - sb.append(","); - } - if (!CDate.isPositiveInfinity(max)) { - sb.append("\"max\":").append(max); - } - sb.append("}"); - return sb.toString(); - } - if(obj instanceof Collection) { - Collection col = (Collection) obj; - // Workaround: Arrow deserializes lists as a JsonStringArrayList which has a JSON String method - @NonNull ResultType elemType = ((ResultType.ListT) type).getElementType(); - return col.stream().map(v -> getPrintValue(v, elemType, settings)).collect(Collectors.joining(",", "[", "]")); - } - return obj.toString(); - } - - private static String getPrintValue(Object obj) { - if(obj instanceof JsonStringArrayList) { - // Workaround: Arrow deserializes lists as a JsonStringArrayList which has a JSON String method - return new ArrayList<>((JsonStringArrayList) obj).stream() - .map(ArrowResultGenerationTest::getPrintValue) - .collect(Collectors.joining(",", "[", "]")); - } - return Objects.toString(obj); - } + } } diff --git a/backend/src/test/java/com/bakdata/conquery/io/result/csv/CsvResultGenerationTest.java b/backend/src/test/java/com/bakdata/conquery/io/result/csv/CsvResultGenerationTest.java index 770bb17270..54ae964fed 100644 --- a/backend/src/test/java/com/bakdata/conquery/io/result/csv/CsvResultGenerationTest.java +++ b/backend/src/test/java/com/bakdata/conquery/io/result/csv/CsvResultGenerationTest.java @@ -12,13 +12,14 @@ import java.util.StringJoiner; import java.util.stream.Collectors; -import com.bakdata.conquery.io.result.ResultTestUtil; import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.i18n.I18n; import com.bakdata.conquery.models.identifiable.mapping.EntityPrintId; import com.bakdata.conquery.models.query.ManagedQuery; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.StringResultPrinters; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.util.NonPersistentStoreFactory; @@ -28,41 +29,41 @@ @Slf4j public class CsvResultGenerationTest { - static { - I18n.init(); - } - - public static final ConqueryConfig CONFIG = new ConqueryConfig(){{ + public static final ConqueryConfig CONFIG = new ConqueryConfig() {{ // Suppress java.lang.NoClassDefFoundError: com/bakdata/conquery/io/jackson/serializer/CurrencyUnitDeserializer setStorage(new NonPersistentStoreFactory()); }}; + static { + I18n.init(); + } @Test void writeAndRead() throws IOException { // Prepare every input data - PrintSettings printSettings = new PrintSettings( - true, - Locale.GERMAN, - null, - CONFIG, - (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), - (selectInfo) -> selectInfo.getSelect().getLabel()); + StringResultPrinters printers = new StringResultPrinters(); + final PrintSettings printSettings = new PrintSettings(true, + Locale.GERMAN, + null, + CONFIG, + (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), + (selectInfo) -> selectInfo.getSelect().getLabel() + ); // The Shard nodes send Object[] but since Jackson is used for deserialization, nested collections are always a list because they are not further specialized - List results = getTestEntityResults(); + final List results = getTestEntityResults(); - ManagedQuery mquery = getTestQuery(); + final ManagedQuery mquery = getTestQuery(); // First we write to the buffer, than we read from it and parse it as TSV - StringWriter writer = new StringWriter(); + final StringWriter writer = new StringWriter(); - CsvRenderer renderer = new CsvRenderer(CONFIG.getCsv().createWriter(writer), printSettings); - renderer.toCSV(ResultTestUtil.ID_FIELDS, mquery.getResultInfos(printSettings), mquery.streamResults(OptionalLong.empty())); + final CsvRenderer renderer = new CsvRenderer(CONFIG.getCsv().createWriter(writer), printSettings); + renderer.toCSV(getIdFields(), mquery.getResultInfos(), mquery.streamResults(OptionalLong.empty()), printSettings); - String computed = writer.toString(); + final String computed = writer.toString(); - String expected = generateExpectedCSV(results, mquery.getResultInfos(printSettings)); + final String expected = generateExpectedCSV(results, mquery.getResultInfos(), printSettings, printers); log.info("Wrote and than read this csv data: {}", computed); @@ -71,31 +72,44 @@ void writeAndRead() throws IOException { } - private String generateExpectedCSV(List results, List resultInfos) { - List expected = new ArrayList<>(); - expected.add(ResultTestUtil.ID_FIELDS.stream().map(info -> info.defaultColumnName()).collect(Collectors.joining(",")) + "," + getResultTypes().stream().map(ResultType::typeInfo).collect(Collectors.joining(",")) + "\n"); + private String generateExpectedCSV(List results, List resultInfos, PrintSettings printSettings, PrinterFactory printerFactory) { + final List expected = new ArrayList<>(); + expected.add(getIdFields().stream().map(info -> info.defaultColumnName(printSettings)).collect(Collectors.joining(",")) + + "," + + getResultTypes().stream() + .map(ResultType::typeInfo) + .collect(Collectors.joining(",")) + + "\n"); + + final String delimiter = String.valueOf(CONFIG.getCsv().getDelimeter()); + results.stream() - .map(EntityResult.class::cast) - .forEach(res -> { - - for (Object[] line : res.listResultLines()) { - StringJoiner valueJoiner = new StringJoiner(","); - valueJoiner.add(String.valueOf(res.getEntityId())); - valueJoiner.add(String.valueOf(res.getEntityId())); - for (int lIdx = 0; lIdx < line.length; lIdx++) { - Object val = line[lIdx]; - if(val == null) { - valueJoiner.add(""); - continue; - } - ResultInfo info = resultInfos.get(lIdx); - final String printVal = info.printNullable(val); - valueJoiner.add(printVal.contains(String.valueOf(CONFIG.getCsv().getDelimeter()))? "\""+printVal+"\"": printVal); - } - - expected.add(valueJoiner + "\n"); - } - }); + .map(EntityResult.class::cast) + .forEach(res -> { + + for (Object[] line : res.listResultLines()) { + final StringJoiner valueJoiner = new StringJoiner(","); + + valueJoiner.add(String.valueOf(res.getEntityId())); + valueJoiner.add(String.valueOf(res.getEntityId())); + + for (int lIdx = 0; lIdx < line.length; lIdx++) { + final Object val = line[lIdx]; + + if (val == null) { + valueJoiner.add(""); + continue; + } + + final ResultInfo info = resultInfos.get(lIdx); + final String printVal = (String) info.createPrinter(printerFactory, printSettings).apply(val); + + valueJoiner.add(printVal.contains(delimiter) ? "\"" + printVal + "\"" : printVal); + } + + expected.add(valueJoiner + "\n"); + } + }); return String.join("", expected); } diff --git a/backend/src/test/java/com/bakdata/conquery/io/result/excel/ExcelResultRenderTest.java b/backend/src/test/java/com/bakdata/conquery/io/result/excel/ExcelResultRenderTest.java index a9bb2101ce..fa50e4ac1c 100644 --- a/backend/src/test/java/com/bakdata/conquery/io/result/excel/ExcelResultRenderTest.java +++ b/backend/src/test/java/com/bakdata/conquery/io/result/excel/ExcelResultRenderTest.java @@ -1,9 +1,7 @@ package com.bakdata.conquery.io.result.excel; -import static com.bakdata.conquery.io.result.ResultTestUtil.getResultTypes; -import static com.bakdata.conquery.io.result.ResultTestUtil.getTestEntityResults; +import static com.bakdata.conquery.io.result.ResultTestUtil.*; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -13,24 +11,25 @@ import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.OptionalLong; import java.util.StringJoiner; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.bakdata.conquery.apiv1.query.Query; import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; import com.bakdata.conquery.io.result.ResultTestUtil; -import com.bakdata.conquery.models.auth.entities.User; import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.config.ExcelConfig; -import com.bakdata.conquery.models.datasets.Dataset; import com.bakdata.conquery.models.i18n.I18n; import com.bakdata.conquery.models.identifiable.mapping.EntityPrintId; import com.bakdata.conquery.models.query.ManagedQuery; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; import com.bakdata.conquery.models.query.resultinfo.SelectResultInfo; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.StringResultPrinters; import com.bakdata.conquery.models.query.results.EntityResult; import com.bakdata.conquery.models.types.ResultType; import com.bakdata.conquery.util.NonPersistentStoreFactory; @@ -46,35 +45,34 @@ @Slf4j public class ExcelResultRenderTest { - static { - I18n.init(); - } - - public static final ConqueryConfig CONFIG = new ConqueryConfig(){{ + public static final ConqueryConfig CONFIG = new ConqueryConfig() {{ // Suppress java.lang.NoClassDefFoundError: com/bakdata/conquery/io/jackson/serializer/CurrencyUnitDeserializer setStorage(new NonPersistentStoreFactory()); }}; private static final List printIdFields = List.of("id1", "id2"); + static { + I18n.init(); + } @Test void writeAndRead() throws IOException { // Prepare every input data - PrintSettings printSettings = new PrintSettings( - true, - Locale.GERMAN, - null, - CONFIG, - (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), - (selectInfo) -> selectInfo.getSelect().getLabel()); + final PrintSettings printSettings = new PrintSettings(true, + Locale.GERMAN, + null, + CONFIG, + (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), + (selectInfo) -> selectInfo.getSelect().getLabel() + ); // The Shard nodes send Object[] but since Jackson is used for deserialization, nested collections are always a list because they are not further specialized - List results = getTestEntityResults(); + final List results = getTestEntityResults(); - ManagedQuery mquery = new ManagedQuery(mock(Query.class), mock(User.class), new Dataset(ExcelResultRenderTest.class.getSimpleName()), null, null) { - public List getResultInfos(PrintSettings printSettings) { + final ManagedQuery mquery = new ManagedQuery(null, OWNER, DATASET, null, null) { + public List getResultInfos() { return getResultTypes().stream() .map(ResultTestUtil.TypedSelectDummy::new) - .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet(), printSettings)) + .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet())) .collect(Collectors.toList()); } @@ -85,23 +83,27 @@ public Stream streamResults(OptionalLong maybeLimit) { }; // First we write to the buffer, than we read from it and parse it as TSV - ByteArrayOutputStream output = new ByteArrayOutputStream(); + final ByteArrayOutputStream output = new ByteArrayOutputStream(); - ExcelRenderer renderer = new ExcelRenderer(new ExcelConfig(),printSettings); + final ExcelRenderer renderer = new ExcelRenderer(new ExcelConfig(), printSettings); - renderer.renderToStream( - ResultTestUtil.ID_FIELDS, - mquery, - output, OptionalLong.empty(), printSettings - ); + renderer.renderToStream(ResultTestUtil.getIdFields(), mquery, output, OptionalLong.empty(), printSettings); - InputStream inputStream = new ByteArrayInputStream(output.toByteArray()); + final InputStream inputStream = new ByteArrayInputStream(output.toByteArray()); - List computed = readComputed(inputStream, printSettings); + final List computed = readComputed(inputStream, printSettings); + // We have to do some magic here to emulate the excel printed results. + PrintSettings tsvPrintSettings = new PrintSettings(true, + Locale.GERMAN, + null, + CONFIG, + (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), + (selectInfo) -> selectInfo.getSelect().getLabel() + ); - List expected = generateExpectedTSV(results, mquery.getResultInfos(printSettings)); + final List expected = generateExpectedTSV(results, mquery.getResultInfos(), tsvPrintSettings, new StringResultPrinters()); log.info("Wrote and than read this excel data: {}", computed); @@ -112,13 +114,13 @@ public Stream streamResults(OptionalLong maybeLimit) { @NotNull private List readComputed(InputStream inputStream, PrintSettings settings) throws IOException { - XSSFWorkbook workbook = new XSSFWorkbook(inputStream); - XSSFSheet sheet = workbook.getSheetAt(0); + final XSSFWorkbook workbook = new XSSFWorkbook(inputStream); + final XSSFSheet sheet = workbook.getSheetAt(0); - List computed = new ArrayList<>(); + final List computed = new ArrayList<>(); for (Row row : sheet) { - StringJoiner sj = new StringJoiner("\t"); - DataFormatter formatter = new DataFormatter(settings.getLocale()); + final StringJoiner sj = new StringJoiner("\t"); + final DataFormatter formatter = new DataFormatter(settings.getLocale()); for (Cell cell : row) { final String formatted = switch (cell.getCellType()) { @@ -136,46 +138,48 @@ private List readComputed(InputStream inputStream, PrintSettings setting } - private List generateExpectedTSV(List results, List resultInfos) { - List expected = new ArrayList<>(); + private List generateExpectedTSV( + List results, List resultInfos, PrintSettings printSettings, PrinterFactory printerFactory) { + final List expected = new ArrayList<>(); expected.add(String.join("\t", printIdFields) + "\t" + getResultTypes().stream().map(ResultType::typeInfo).collect(Collectors.joining("\t"))); results.stream() - .map(EntityResult.class::cast) - .forEach(res -> { - - for (Object[] line : res.listResultLines()) { - StringJoiner valueJoiner = new StringJoiner("\t"); - valueJoiner.add(String.valueOf(res.getEntityId())); - valueJoiner.add(String.valueOf(res.getEntityId())); - for (int lIdx = 0; lIdx < line.length; lIdx++) { - Object val = line[lIdx]; - if(val == null) { - valueJoiner.add("null"); - continue; - } - ResultInfo info = resultInfos.get(lIdx); - joinValue(valueJoiner, val, info); - } - expected.add(valueJoiner.toString()); - } - }); + .map(EntityResult.class::cast) + .forEach(res -> { + + for (Object[] line : res.listResultLines()) { + final StringJoiner valueJoiner = new StringJoiner("\t"); + + valueJoiner.add(String.valueOf(res.getEntityId())); + valueJoiner.add(String.valueOf(res.getEntityId())); + + for (int lIdx = 0; lIdx < line.length; lIdx++) { + final Object val = line[lIdx]; + + final ResultInfo info = resultInfos.get(lIdx); + final String printed = printValue(val, info, printSettings, printerFactory); + + valueJoiner.add(printed); + } + expected.add(valueJoiner.toString()); + } + }); return expected; } - private void joinValue(StringJoiner valueJoiner, Object val, ResultInfo info) { - String printVal = info.printNullable(val); + private String printValue(Object val, ResultInfo info, PrintSettings printSettings, PrinterFactory printerFactory) { + if (val == null) { + return "null"; + } + + final Printer printer = info.createPrinter(printerFactory, printSettings); if (info.getType().equals(ResultType.Primitive.BOOLEAN)) { // Even though we set the locale to GERMAN, poi's {@link DataFormatter#formatCellValue(Cell)} hardcoded english booleans - printVal = (Boolean) val ? "TRUE" : "FALSE"; - } - - if(info.getType().equals(ResultType.Primitive.MONEY)){ - printVal = printVal.replace(" ", " "); + return (Boolean) val ? "TRUE" : "FALSE"; } - valueJoiner.add(printVal); + return Objects.toString(printer.apply(val)); } } diff --git a/backend/src/test/java/com/bakdata/conquery/io/result/parquet/ParquetResultGenerationTest.java b/backend/src/test/java/com/bakdata/conquery/io/result/parquet/ParquetResultGenerationTest.java index 8751490399..0b6a5e4f85 100644 --- a/backend/src/test/java/com/bakdata/conquery/io/result/parquet/ParquetResultGenerationTest.java +++ b/backend/src/test/java/com/bakdata/conquery/io/result/parquet/ParquetResultGenerationTest.java @@ -16,7 +16,6 @@ import java.util.stream.Collectors; import com.bakdata.conquery.apiv1.query.concept.specific.CQConcept; -import com.bakdata.conquery.io.result.ResultTestUtil; import com.bakdata.conquery.io.result.arrow.ArrowResultGenerationTest; import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.i18n.I18n; @@ -56,9 +55,9 @@ void generateSchema() { final UniqueNamer uniqueNamer = new UniqueNamer(PRINT_SETTINGS); List resultInfos = getResultTypes().stream().map(TypedSelectDummy::new) - .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet(), PRINT_SETTINGS)).collect(Collectors.toList()); + .map(select -> new SelectResultInfo(select, new CQConcept(), Collections.emptySet())).collect(Collectors.toList()); - final MessageType messageType = EntityResultWriteSupport.generateSchema(ResultTestUtil.ID_FIELDS, resultInfos, uniqueNamer); + final MessageType messageType = EntityResultWriteSupport.generateSchema(getIdFields(), resultInfos, uniqueNamer, PRINT_SETTINGS); assertThat(messageType).isEqualTo( Types.buildMessage() @@ -104,13 +103,12 @@ void writeAndRead() throws IOException { I18n.init(); // Prepare every input data - PrintSettings printSettings = new PrintSettings( - false, - Locale.ROOT, - null, - CONFIG, - (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), - (selectInfo) -> selectInfo.getSelect().getLabel() + PrintSettings printSettings = new PrintSettings(false, + Locale.ROOT, + null, + CONFIG, + (cer) -> EntityPrintId.from(cer.getEntityId(), cer.getEntityId()), + (selectInfo) -> selectInfo.getSelect().getLabel() ); // The Shard nodes send Object[] but since Jackson is used for deserialization, nested collections are always a list because they are not further specialized List results = getTestEntityResults(); @@ -119,7 +117,7 @@ void writeAndRead() throws IOException { // First we write to the buffer, than we read from it and parse it as TSV ByteArrayOutputStream output = new ByteArrayOutputStream(); - ParquetRenderer.writeToStream(output, ResultTestUtil.ID_FIELDS, managedQuery.getResultInfos(printSettings), printSettings, managedQuery.streamResults(OptionalLong.empty())); + ParquetRenderer.writeToStream(output, getIdFields(), managedQuery.getResultInfos(), printSettings, managedQuery.streamResults(OptionalLong.empty())); final byte[] buf = output.toByteArray(); @@ -141,7 +139,7 @@ void writeAndRead() throws IOException { log.info("\n{}", actual); - assertThat(actual).isEqualTo(ArrowResultGenerationTest.generateExpectedTSV(results, managedQuery.getResultInfos(printSettings), printSettings)); + assertThat(actual).isEqualTo(ArrowResultGenerationTest.generateExpectedTSV(results, managedQuery.getResultInfos())); } diff --git a/backend/src/test/java/com/bakdata/conquery/models/events/stores/types/ColumnStoreSerializationTests.java b/backend/src/test/java/com/bakdata/conquery/models/events/stores/types/ColumnStoreSerializationTests.java index 6811691944..22de3ff2dd 100644 --- a/backend/src/test/java/com/bakdata/conquery/models/events/stores/types/ColumnStoreSerializationTests.java +++ b/backend/src/test/java/com/bakdata/conquery/models/events/stores/types/ColumnStoreSerializationTests.java @@ -54,6 +54,7 @@ public class ColumnStoreSerializationTests { private static final CentralRegistry CENTRAL_REGISTRY = new CentralRegistry(); private static ObjectMapper shardInternalMapper; + private static ConqueryConfig config; @BeforeAll public static void setupRegistry() { @@ -61,7 +62,8 @@ public static void setupRegistry() { // Prepare shard node internal mapper - InternalMapperFactory internalMapperFactory = new InternalMapperFactory(new ConqueryConfig(), Validators.newValidator()); + config = new ConqueryConfig(); + InternalMapperFactory internalMapperFactory = new InternalMapperFactory(config, Validators.newValidator()); shardInternalMapper = internalMapperFactory.createWorkerPersistenceMapper(mock(ShardWorkers.class)); } @@ -88,7 +90,7 @@ public static List createCTypes() { return Arrays.asList( new ScaledDecimalStore(13, IntArrayStore.create(10)), - new MoneyIntStore(IntArrayStore.create(10)), + new MoneyIntStore(IntArrayStore.create(10), 2).config(config), new DirectDateRangeStore(IntegerDateStore.create(10), IntegerDateStore.create(10)), new QuarterDateRangeStore(LongArrayStore.create(10)), new IntegerDateStore(LongArrayStore.create(10)), diff --git a/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java b/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java index 8782a45152..bc54baed36 100644 --- a/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java +++ b/backend/src/test/java/com/bakdata/conquery/models/query/DefaultColumnNameTest.java @@ -169,9 +169,9 @@ void checkCombinations(TestConcept concept, boolean hasCQConceptLabel, String ex final CQConcept cqConcept = concept.createCQConcept(hasCQConceptLabel); final UniqueNamer uniqNamer = new UniqueNamer(SETTINGS); - SelectResultInfo info = new SelectResultInfo(concept.extractSelect(cqConcept), cqConcept, Collections.emptySet(), SETTINGS); + SelectResultInfo info = new SelectResultInfo(concept.extractSelect(cqConcept), cqConcept, Collections.emptySet()); - assertThat(uniqNamer.getUniqueName(info)).isEqualTo(expectedColumnName); + assertThat(uniqNamer.getUniqueName(info, SETTINGS)).isEqualTo(expectedColumnName); } diff --git a/backend/src/test/java/com/bakdata/conquery/models/query/UniqueNameTest.java b/backend/src/test/java/com/bakdata/conquery/models/query/UniqueNameTest.java index 441b6ef2bf..c95a6d3a01 100644 --- a/backend/src/test/java/com/bakdata/conquery/models/query/UniqueNameTest.java +++ b/backend/src/test/java/com/bakdata/conquery/models/query/UniqueNameTest.java @@ -16,14 +16,14 @@ void testNameCollision() { PrintSettings settings = new PrintSettings(true, Locale.ROOT, null, new ConqueryConfig(), null, null); final UniqueNamer uniqueNamer = new UniqueNamer(settings); - final ExternalResultInfo info1 = new ExternalResultInfo("test", ResultType.Primitive.STRING, settings); - final ExternalResultInfo info2 = new ExternalResultInfo("test", ResultType.Primitive.STRING, settings); - final ExternalResultInfo info3 = new ExternalResultInfo("test_1", ResultType.Primitive.STRING, settings); - final ExternalResultInfo info4 = new ExternalResultInfo("test", ResultType.Primitive.STRING, settings); + final ExternalResultInfo info1 = new ExternalResultInfo("test", ResultType.Primitive.STRING); + final ExternalResultInfo info2 = new ExternalResultInfo("test", ResultType.Primitive.STRING); + final ExternalResultInfo info3 = new ExternalResultInfo("test_1", ResultType.Primitive.STRING); + final ExternalResultInfo info4 = new ExternalResultInfo("test", ResultType.Primitive.STRING); - assertThat(uniqueNamer.getUniqueName(info1)).isEqualTo("test"); - assertThat(uniqueNamer.getUniqueName(info2)).isEqualTo("test_1"); - assertThat(uniqueNamer.getUniqueName(info3)).isEqualTo("test_1_1"); - assertThat(uniqueNamer.getUniqueName(info4)).isEqualTo("test_2"); + assertThat(uniqueNamer.getUniqueName(info1, settings)).isEqualTo("test"); + assertThat(uniqueNamer.getUniqueName(info2, settings)).isEqualTo("test_1"); + assertThat(uniqueNamer.getUniqueName(info3, settings)).isEqualTo("test_1_1"); + assertThat(uniqueNamer.getUniqueName(info4, settings)).isEqualTo("test_2"); } } diff --git a/backend/src/test/java/com/bakdata/conquery/models/types/ResultTypeTest.java b/backend/src/test/java/com/bakdata/conquery/models/types/ResultTypeTest.java index 45888ecd27..f66f7fff5b 100644 --- a/backend/src/test/java/com/bakdata/conquery/models/types/ResultTypeTest.java +++ b/backend/src/test/java/com/bakdata/conquery/models/types/ResultTypeTest.java @@ -11,14 +11,16 @@ import java.util.Map; import com.bakdata.conquery.io.jackson.Jackson; +import com.bakdata.conquery.models.common.CDate; import com.bakdata.conquery.models.config.ConqueryConfig; import com.bakdata.conquery.models.forms.util.Resolution; import com.bakdata.conquery.models.i18n.I18n; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.models.query.resultinfo.ExternalResultInfo; import com.bakdata.conquery.models.query.resultinfo.ResultInfo; -import com.bakdata.conquery.models.query.resultinfo.printers.ResultPrinters; -import com.google.common.collect.ImmutableMap; +import com.bakdata.conquery.models.query.resultinfo.printers.Printer; +import com.bakdata.conquery.models.query.resultinfo.printers.PrinterFactory; +import com.bakdata.conquery.models.query.resultinfo.printers.StringResultPrinters; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -30,6 +32,8 @@ public class ResultTypeTest { private static final PrintSettings PRETTY_DE = new PrintSettings(true, Locale.GERMANY, null, CONFIG, null, null); private static final PrintSettings PLAIN = new PrintSettings(false, Locale.ENGLISH, null, CONFIG, null, null); + private static PrinterFactory PRINTERS = new StringResultPrinters(); + static { // Initialization of the internationalization I18n.init(); @@ -38,83 +42,100 @@ public class ResultTypeTest { CONFIG.getLocale().setDateFormatMapping(Map.of(Locale.GERMAN, "dd.MM.yyyy")); } + @SuppressWarnings("unused") public static List testData() { - return List.of( - //TODO Arguments.of(PRETTY, ConqueryConstants.formResolutionInfo(PLAIN), Resolution.COMPLETE.name(), "complete"), -//TODO Arguments.of(PRETTY_DE, ConqueryConstants.formResolutionInfo(PLAIN), Resolution.COMPLETE.name(), "Gesamt"), - - Arguments.of(PRETTY, ResultType.Primitive.BOOLEAN, true, "Yes"), - Arguments.of(PRETTY, ResultType.Primitive.BOOLEAN, false, "No"), - Arguments.of(PRETTY, ResultType.Primitive.STRING, "test", "test"), - Arguments.of(PRETTY, ResultType.Primitive.DATE, LocalDate.of(2013, 7, 12).toEpochDay(), "2013-07-12"), - Arguments.of(PRETTY_DE, ResultType.Primitive.DATE, LocalDate.of(2013, 7, 12).toEpochDay(), "12.07.2013"), - Arguments.of(PRETTY, ResultType.Primitive.DATE_RANGE, List.of(Long.valueOf(LocalDate.of(2013, 7, 12).toEpochDay()) - .intValue(), Long.valueOf(LocalDate.of(2013, 7, 12).toEpochDay()) - .intValue()), "2013-07-12"), - Arguments.of(PRETTY_DE, ResultType.Primitive.DATE_RANGE, List.of(Long.valueOf(LocalDate.of(2013, 7, 12).toEpochDay()) - .intValue(), Long.valueOf(LocalDate.of(2013, 7, 12).toEpochDay()) - .intValue()), "12.07.2013"), - Arguments.of(PRETTY, ResultType.Primitive.DATE_RANGE, List.of(Long.valueOf(LocalDate.of(2013, 7, 12).toEpochDay()) - .intValue(), Long.valueOf(LocalDate.of(2014, 7, 12).toEpochDay()) - .intValue()), "2013-07-12/2014-07-12"), - Arguments.of(PRETTY_DE, ResultType.Primitive.DATE_RANGE, List.of(Long.valueOf(LocalDate.of(2013, 7, 12).toEpochDay()) - .intValue(), Long.valueOf(LocalDate.of(2014, 7, 12).toEpochDay()) - .intValue()), "12.07.2013 - 12.07.2014"), - Arguments.of(PRETTY, ResultType.Primitive.INTEGER, 51839274, "51,839,274"), - Arguments.of(PRETTY_DE, ResultType.Primitive.INTEGER, 51839274, "51.839.274"), - Arguments.of(PRETTY, ResultType.Primitive.MONEY, 51839274L, "€518,392.74"), - Arguments.of(PRETTY_DE, ResultType.Primitive.MONEY, 51839274L, "518.392,74 €"), - Arguments.of(PRETTY, ResultType.Primitive.NUMERIC, 0.2, "0.2"), - Arguments.of(PRETTY_DE, ResultType.Primitive.NUMERIC, 0.2, "0,2"), - Arguments.of(PRETTY, ResultType.Primitive.NUMERIC, new BigDecimal("716283712389817246892743124.12312"), "716,283,712,389,817,246,892,743,124.12312"), - Arguments.of(PRETTY_DE, ResultType.Primitive.NUMERIC, new BigDecimal("716283712389817246892743124.12312"), "716.283.712.389.817.246.892.743.124,12312"), - Arguments.of(PRETTY, ResultType.Primitive.STRING, "test", "test"), - - Arguments.of(PLAIN, ResultType.Primitive.BOOLEAN, true, "1"), - Arguments.of(PLAIN, ResultType.Primitive.BOOLEAN, false, "0"), - Arguments.of(PLAIN, ResultType.Primitive.STRING, "test", "test"), - Arguments.of(PLAIN, ResultType.Primitive.DATE, LocalDate.of(2013, 7, 12).toEpochDay(), "2013-07-12"), - Arguments.of(PLAIN, ResultType.Primitive.INTEGER, 51839274, "51839274"), - Arguments.of(PLAIN, ResultType.Primitive.MONEY, 51839274L, "51839274"), - Arguments.of(PLAIN, ResultType.Primitive.NUMERIC, 0.2, "0.2"), - Arguments.of(PLAIN, ResultType.Primitive.NUMERIC, new BigDecimal("716283712389817246892743124.12312"), "716283712389817246892743124.12312"), - Arguments.of(PLAIN, ResultType.Primitive.STRING, "test", "test"), - Arguments.of(PLAIN, ResultType.Primitive.STRING, Resolution.COMPLETE.name(), "COMPLETE"), // TODO fk: is supposed not to test the mapping? - Arguments.of(PLAIN, ResultType.Primitive.STRING, ImmutableMap.of("a", 2, "c", 1), "{a=2, c=1}") + return List.of(Arguments.of(PRETTY, ResultType.Primitive.BOOLEAN, true, "Yes"), + Arguments.of(PRETTY, ResultType.Primitive.BOOLEAN, false, "No"), + Arguments.of(PRETTY, ResultType.Primitive.STRING, "test", "test"), + Arguments.of(PRETTY, ResultType.Primitive.DATE, CDate.ofLocalDate(LocalDate.of(2013, 7, 12)), "2013-07-12"), + Arguments.of(PRETTY_DE, ResultType.Primitive.DATE, CDate.ofLocalDate(LocalDate.of(2013, 7, 12)), "12.07.2013"), + Arguments.of(PRETTY, + ResultType.Primitive.DATE_RANGE, + List.of(CDate.ofLocalDate(LocalDate.of(2013, 7, 12)), CDate.ofLocalDate(LocalDate.of(2013, 7, 12))), + "2013-07-12" + ), + Arguments.of(PRETTY_DE, + ResultType.Primitive.DATE_RANGE, + List.of(CDate.ofLocalDate(LocalDate.of(2013, 7, 12)), CDate.ofLocalDate(LocalDate.of(2013, 7, 12))), + "12.07.2013" + ), + Arguments.of(PRETTY, + ResultType.Primitive.DATE_RANGE, + List.of(CDate.ofLocalDate(LocalDate.of(2013, 7, 12)), CDate.ofLocalDate(LocalDate.of(2014, 7, 12))), + "2013-07-12/2014-07-12" + ), + Arguments.of(PRETTY_DE, + ResultType.Primitive.DATE_RANGE, + List.of(CDate.ofLocalDate(LocalDate.of(2013, 7, 12)), CDate.ofLocalDate(LocalDate.of(2014, 7, 12))), + "12.07.2013 - 12.07.2014" + ), + Arguments.of(PRETTY, ResultType.Primitive.INTEGER, 51839274L, "51,839,274"), + Arguments.of(PRETTY_DE, ResultType.Primitive.INTEGER, 51839274L, "51.839.274"), + Arguments.of(PRETTY, ResultType.Primitive.MONEY, new BigDecimal("518392.74"), "€518,392.74"), + Arguments.of(PRETTY_DE, ResultType.Primitive.MONEY, new BigDecimal("518392.74"), "518.392,74\u00A0€"), + Arguments.of(PRETTY, ResultType.Primitive.NUMERIC, 0.2, "0.2"), + Arguments.of(PRETTY_DE, ResultType.Primitive.NUMERIC, 0.2, "0,2"), + Arguments.of(PRETTY, + ResultType.Primitive.NUMERIC, + new BigDecimal("716283712389817246892743124.12312"), + "716,283,712,389,817,246,892,743,124.12312" + ), + Arguments.of(PRETTY_DE, + ResultType.Primitive.NUMERIC, + new BigDecimal("716283712389817246892743124.12312"), + "716.283.712.389.817.246.892.743.124,12312" + ), + Arguments.of(PRETTY, ResultType.Primitive.STRING, "test", "test"), + + Arguments.of(PLAIN, ResultType.Primitive.BOOLEAN, true, "1"), + Arguments.of(PLAIN, ResultType.Primitive.BOOLEAN, false, "0"), + Arguments.of(PLAIN, ResultType.Primitive.STRING, "test", "test"), + Arguments.of(PLAIN, ResultType.Primitive.DATE, LocalDate.of(2013, 7, 12).toEpochDay(), "2013-07-12"), + Arguments.of(PLAIN, ResultType.Primitive.INTEGER, 51839274L, "51839274"), + Arguments.of(PLAIN, ResultType.Primitive.MONEY, new BigDecimal(51839274L), "51839274"), + Arguments.of(PLAIN, ResultType.Primitive.NUMERIC, 0.2, "0.2"), + Arguments.of(PLAIN, + ResultType.Primitive.NUMERIC, + new BigDecimal("716283712389817246892743124.12312"), + "716283712389817246892743124.12312" + ), + Arguments.of(PLAIN, ResultType.Primitive.STRING, "test", "test"), + Arguments.of(PLAIN, ResultType.Primitive.STRING, Resolution.COMPLETE.name(), "COMPLETE") ); } - public static ResultInfo info(ResultType type, PrintSettings settings) { - return new ExternalResultInfo("col", type, settings); - } - @ParameterizedTest(name = "{0} {1}: {2} -> {3}") @MethodSource("testData") - public void testPrinting(PrintSettings cfg, ResultType type, Object value, String expected) throws IOException { - ResultInfo info = info(type, cfg); + public void testPrinting(PrintSettings printSettings, ResultType type, Object value, String expected) throws IOException { + ResultInfo info = info(type); - final ResultPrinters.Printer printer = info.getPrinter(); - assertThat(printer.print(value)).isEqualTo(expected); + final Printer printer = info.createPrinter(PRINTERS, printSettings); + + assertThat(printer.apply(value)).isEqualTo(expected); final String str = Jackson.MAPPER.writeValueAsString(value); final Object copy = Jackson.MAPPER.readValue(str, Object.class); - assertThat(printer.print(copy)).isEqualTo(expected); + assertThat(printer.apply(copy)).isEqualTo(expected); + } + + public static ResultInfo info(ResultType type) { + return new ExternalResultInfo("col", type); } @ParameterizedTest(name = "{1}: {2}") @MethodSource("testData") - public void testBinaryPrinting(PrintSettings cfg, ResultType type, Object value, String expected) throws IOException { - ResultInfo info = info(type, cfg); + public void testBinaryPrinting(PrintSettings printSettings, ResultType type, Object value, String expected) throws IOException { + ResultInfo info = info(type); - final ResultPrinters.Printer printer = info.getPrinter(); - assertThat(printer.print(value)).isEqualTo(expected); + final Printer printer = info.createPrinter(PRINTERS, printSettings); + assertThat(printer.apply(value)).isEqualTo(expected); final byte[] bytes = Jackson.BINARY_MAPPER.writeValueAsBytes(value); final Object copy = Jackson.BINARY_MAPPER.readValue(bytes, Object.class); - assertThat(printer.print(copy)).isEqualTo(expected); + assertThat(printer.apply(copy)).isEqualTo(expected); } } diff --git a/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json deleted file mode 100644 index 8c624cf0e2..0000000000 --- a/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "type": "QUERY_TEST", - "label": "MULTI_SELECT_AGGREGATOR Test", - "expectedCsv": "tests/aggregator/MULTI_SELECT_AGGREGATOR/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "ids": [ - "concept" - ], - "type": "CONCEPT", - "tables": [ - { - "id": "concept.connector", - "selects": [ - "concept.connector.select" - ] - } - ] - } - }, - "concepts": [ - { - "name": "concept", - "type": "TREE", - "connectors": [ - { - "label": "connector", - "table": "table", - "validityDates": { - "label": "datum", - "column": "table.datum" - }, - "selects": { - "type": "COUNT_OCCURENCES", - "name" : "select", - "column": "table.value", - "selection": [ - "f", - "m" - ] - } - } - ] - } - ], - "content": { - "tables": [ - { - "csv": "tests/aggregator/MULTI_SELECT_AGGREGATOR/content.csv", - "name": "table", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - }, - { - "name": "value", - "type": "STRING" - } - ] - } - ] - } -} diff --git a/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/content.csv b/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/content.csv deleted file mode 100644 index 5358e7b61a..0000000000 --- a/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/content.csv +++ /dev/null @@ -1,10 +0,0 @@ -pid,datum,value -1,2012-01-01,"f" -1,2012-01-02,"f" -2,2010-07-15, -3,2013-11-10,"f" -4,2012-11-11,"m" -5,2012-11-11,"x" -5,2012-11-11,"f" -6,2012-11-11,"m" -6,2012-11-11,"f" diff --git a/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/expected.csv b/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/expected.csv deleted file mode 100644 index 15ec609372..0000000000 --- a/backend/src/test/resources/tests/aggregator/MULTI_SELECT_AGGREGATOR/expected.csv +++ /dev/null @@ -1,7 +0,0 @@ -result,dates,concept select -2,{2010-07-15/2010-07-15}, -3,{2013-11-10/2013-11-10},{f=1} -6,{2012-11-11/2012-11-11},"{f=1, m=1}" -1,{2012-01-01/2012-01-02},{f=2} -4,{2012-11-11/2012-11-11},{m=1} -5,{2012-11-11/2012-11-11},{f=1} \ No newline at end of file diff --git a/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json b/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json deleted file mode 100644 index 59a83c0f6e..0000000000 --- a/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/SIMPLE_VIRTUAL_CONCEPT_Query.test.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "type": "QUERY_TEST", - "label": "SELECT_AGGREGATOR Test", - "expectedCsv": "tests/aggregator/SELECT_AGGREGATOR/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "ids": [ - "concept" - ], - "type": "CONCEPT", - "tables": [ - { - "id": "concept.connector", - "selects": [ - "concept.connector.select" - ] - } - ] - } - }, - "concepts": [ - { - "name": "concept", - "type": "TREE", - "connectors": [ - { - "label": "connector", - "table": "table", - "validityDates": { - "label": "datum", - "column": "table.datum" - }, - "selects": { - "type": "COUNT_OCCURENCES", - "name": "select", - "column": "table.value", - "selection": "f" - } - } - ] - } - ], - "content": { - "tables": [ - { - "csv": "tests/aggregator/SELECT_AGGREGATOR/content.csv", - "name": "table", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "datum", - "type": "DATE" - }, - { - "name": "value", - "type": "STRING" - } - ] - } - ] - } -} diff --git a/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/content.csv b/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/content.csv deleted file mode 100644 index cadb60f0f0..0000000000 --- a/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/content.csv +++ /dev/null @@ -1,6 +0,0 @@ -pid,datum,value -1,2012-01-01,"f" -1,2012-01-02,"f" -2,2010-07-15, -3,2013-11-10,"f" -4,2012-11-11,"m" diff --git a/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/expected.csv b/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/expected.csv deleted file mode 100644 index f01e356de2..0000000000 --- a/backend/src/test/resources/tests/aggregator/SELECT_AGGREGATOR/expected.csv +++ /dev/null @@ -1,5 +0,0 @@ -result,dates,concept select -1,{2012-01-01/2012-01-02},2 -2,{2010-07-15/2010-07-15}, -3,{2013-11-10/2013-11-10},1 -4,{2012-11-11/2012-11-11}, \ No newline at end of file diff --git a/backend/src/test/resources/tests/sql/filter/number_money/real_range/content.csv b/backend/src/test/resources/tests/sql/filter/number_money/real_range/content.csv deleted file mode 100644 index 1cb67fbcf4..0000000000 --- a/backend/src/test/resources/tests/sql/filter/number_money/real_range/content.csv +++ /dev/null @@ -1,19 +0,0 @@ -pid,nr -1,50 -2,250 -3,150 -3,150 -4,50 -4,150 -5,250 -5,150 -6,50 -6,250 -7,150.01 -8,200.01 -9,99.99 -10, -11, -11,300 -12,150 -12, diff --git a/backend/src/test/resources/tests/sql/filter/number_money/real_range/expected.csv b/backend/src/test/resources/tests/sql/filter/number_money/real_range/expected.csv deleted file mode 100644 index 235c68aa46..0000000000 --- a/backend/src/test/resources/tests/sql/filter/number_money/real_range/expected.csv +++ /dev/null @@ -1,6 +0,0 @@ -result,dates -3,{} -4,{} -5,{} -9,{} -12,{} diff --git a/backend/src/test/resources/tests/sql/filter/number_money/real_range/number_money.spec.json b/backend/src/test/resources/tests/sql/filter/number_money/real_range/number_money.spec.json deleted file mode 100644 index 9c869eaf1b..0000000000 --- a/backend/src/test/resources/tests/sql/filter/number_money/real_range/number_money.spec.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "label": "Single Number-Real-Range Filter Query with REAL RANGE on column with MONEY type", - "type": "QUERY_TEST", - "sqlSpec": { - "isEnabled": true - }, - "expectedCsv": "tests/sql/filter/number_money/real_range/expected.csv", - "query": { - "type": "CONCEPT_QUERY", - "root": { - "type": "AND", - "children": [ - { - "ids": [ - "number" - ], - "type": "CONCEPT", - "label": "vs", - "tables": [ - { - "id": "number.number_connector", - "filters": [ - { - "filter": "number.number_connector.money_number_filter", - "type": "REAL_RANGE", - "value": { - "min": 99.00, - "max": 150.00 - } - } - ] - } - ] - } - ] - } - }, - "concepts": [ - { - "label": "number", - "type": "TREE", - "connectors": [ - { - "label": "number_connector", - "table": "table1", - "filters": { - "name": "money_number_filter", - "column": "table1.money", - "type": "NUMBER" - } - } - ] - } - ], - "content": { - "tables": [ - { - "csv": "tests/sql/filter/number_money/real_range/content.csv", - "name": "table1", - "primaryColumn": { - "name": "pid", - "type": "STRING" - }, - "columns": [ - { - "name": "money", - "type": "MONEY" - } - ] - } - ] - } -} diff --git a/cypress/e2e/backend-admin-ui/test_2_dataset.cy.js b/cypress/e2e/backend-admin-ui/test_2_dataset.cy.js index a57f95ea41..746335e4f4 100644 --- a/cypress/e2e/backend-admin-ui/test_2_dataset.cy.js +++ b/cypress/e2e/backend-admin-ui/test_2_dataset.cy.js @@ -139,7 +139,7 @@ context("Admin UI Single Dataset", () => { it("Counts are right", () => { visitAdminUI(`datasets/${testDSID}/connectors/${testDSID}.concept1.column`); cy.get('[data-test-id="accordion-Filters"] > .card-header').contains("20 entries"); - cy.get('[data-test-id="accordion-Selects"] > .card-header').contains("17 entries"); + cy.get('[data-test-id="accordion-Selects"] > .card-header').contains("16 entries"); }); }); diff --git a/cypress/support/test_data/all_types.concept.json b/cypress/support/test_data/all_types.concept.json index 36e7d64ab8..c629b0c7d7 100644 --- a/cypress/support/test_data/all_types.concept.json +++ b/cypress/support/test_data/all_types.concept.json @@ -159,12 +159,6 @@ "type": "RANDOM", "column": "table.INTEGER" }, - { - "label": "COUNT_OCCURENCES", - "type": "COUNT_OCCURENCES", - "column": "table.STRING", - "selection": [] - }, { "label": "FIRST", "type": "FIRST", diff --git a/frontend/src/js/entity-history/timeline/EventCard.tsx b/frontend/src/js/entity-history/timeline/EventCard.tsx index ce0d50c8b9..9fed38d023 100644 --- a/frontend/src/js/entity-history/timeline/EventCard.tsx +++ b/frontend/src/js/entity-history/timeline/EventCard.tsx @@ -161,7 +161,7 @@ const EventCard = ({ {...currencyConfig} suffix={" " + currencyConfig.unit} displayType="text" - value={parseInt(row[column.label] as string) / 100} + value={parseFloat(row[column.label] as string)} /> diff --git a/frontend/src/js/entity-history/timeline/GroupedContent.tsx b/frontend/src/js/entity-history/timeline/GroupedContent.tsx index 9f16b1368a..2c1758ba94 100644 --- a/frontend/src/js/entity-history/timeline/GroupedContent.tsx +++ b/frontend/src/js/entity-history/timeline/GroupedContent.tsx @@ -172,7 +172,7 @@ const Cell = memo( ); } From 5c8f1a2b0c6d2261a42412e667ad1f3ad9b8bc18 Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 11:17:16 +0200 Subject: [PATCH 02/28] Refactor search logic a bit for clarification --- frontend/src/js/concept-trees/globalTreeStoreHelper.ts | 3 +-- frontend/src/js/concept-trees/search.ts | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/frontend/src/js/concept-trees/globalTreeStoreHelper.ts b/frontend/src/js/concept-trees/globalTreeStoreHelper.ts index d16409b7dd..3f5ceee48e 100644 --- a/frontend/src/js/concept-trees/globalTreeStoreHelper.ts +++ b/frontend/src/js/concept-trees/globalTreeStoreHelper.ts @@ -181,9 +181,8 @@ export const globalSearch = async (trees: TreesT, query: string) => { // TODO: Refactor the state and keep both root trees as well as concept trees in a single format // Then simply use that here const formattedTrees = Object.fromEntries( - Object.keys(trees).map((key) => [key, { [key]: trees[key] }]), + Object.entries(trees).map(([key, value]) => [key, { [key]: value }]), ); - const combinedTrees = Object.assign({}, formattedTrees, window.conceptTrees); const result = Object.keys(combinedTrees) diff --git a/frontend/src/js/concept-trees/search.ts b/frontend/src/js/concept-trees/search.ts index f8d5db083c..6dc35ada9a 100644 --- a/frontend/src/js/concept-trees/search.ts +++ b/frontend/src/js/concept-trees/search.ts @@ -58,17 +58,17 @@ export const findConcepts = ( // Count node as 1 already, if it matches let sum = isNodeIncluded ? 1 : 0; - for (const child of node.children) { + for (const childId of node.children) { const result = findConcepts( trees, treeId, - child, - trees[treeId][child], + childId, + trees[treeId][childId], query, intermediateResult, ); - sum += result[child] || 0; + sum += result[childId] || 0; } if (sum !== 0) { From 40b62f3def2261861cb5f564d315fd4447b852f2 Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 11:32:39 +0200 Subject: [PATCH 03/28] Collect the children ids up to the first non-folder children --- .../js/concept-trees/ConceptTreeListItem.tsx | 23 +++++++++++++++++-- frontend/src/js/concept-trees/selectors.ts | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/frontend/src/js/concept-trees/ConceptTreeListItem.tsx b/frontend/src/js/concept-trees/ConceptTreeListItem.tsx index b5f4bda0cb..6757b0ca95 100644 --- a/frontend/src/js/concept-trees/ConceptTreeListItem.tsx +++ b/frontend/src/js/concept-trees/ConceptTreeListItem.tsx @@ -1,11 +1,24 @@ +import { useMemo } from "react"; import type { ConceptIdT } from "../api/types"; import ConceptTree from "./ConceptTree"; import ConceptTreeFolder from "./ConceptTreeFolder"; import { getConceptById } from "./globalTreeStoreHelper"; -import type { SearchT, TreesT } from "./reducer"; +import type { LoadedConcept, SearchT, TreesT } from "./reducer"; import { isNodeInSearchResult } from "./selectors"; +const getNonFolderChildren = (trees: TreesT, node: LoadedConcept): string[] => { + if (node.detailsAvailable) return node.children || []; + + if (!node.children) return []; + + // recursively get children of children + return node.children.reduce((acc, childId) => { + const child = trees[childId]; + return acc.concat(getNonFolderChildren(trees, child)); + }, [] as ConceptIdT[]); +}; + const ConceptTreeListItem = ({ trees, conceptId, @@ -19,7 +32,13 @@ const ConceptTreeListItem = ({ }) => { const tree = trees[conceptId]; - if (!isNodeInSearchResult(conceptId, search, tree.children)) return null; + const nonFolderChildren = useMemo(() => { + if (tree.detailsAvailable) return tree.children; + + return getNonFolderChildren(trees, tree); + }, [trees, tree]); + + if (!isNodeInSearchResult(conceptId, search, nonFolderChildren)) return null; const rootConcept = getConceptById(conceptId); diff --git a/frontend/src/js/concept-trees/selectors.ts b/frontend/src/js/concept-trees/selectors.ts index 853c7d3871..5d02b79201 100644 --- a/frontend/src/js/concept-trees/selectors.ts +++ b/frontend/src/js/concept-trees/selectors.ts @@ -15,7 +15,7 @@ const isChildWithinResults = (children: ConceptIdT[], search: SearchT) => { export const isNodeInSearchResult = ( id: ConceptIdT, search: SearchT, - children?: ConceptIdT[], + children?: ConceptIdT[], // actual concept tree ids, not folder ids ) => { if (!search.result) return true; From 3acda43fdbc044686b5619324a3c7bbe429b2d4f Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 11:44:11 +0200 Subject: [PATCH 04/28] Clarify types and comment --- frontend/src/js/concept-trees/ConceptTreeListItem.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/js/concept-trees/ConceptTreeListItem.tsx b/frontend/src/js/concept-trees/ConceptTreeListItem.tsx index 6757b0ca95..ccf9174a8a 100644 --- a/frontend/src/js/concept-trees/ConceptTreeListItem.tsx +++ b/frontend/src/js/concept-trees/ConceptTreeListItem.tsx @@ -12,11 +12,11 @@ const getNonFolderChildren = (trees: TreesT, node: LoadedConcept): string[] => { if (!node.children) return []; - // recursively get children of children - return node.children.reduce((acc, childId) => { + // collect all non-folder children, recursively + return node.children.reduce((acc, childId) => { const child = trees[childId]; return acc.concat(getNonFolderChildren(trees, child)); - }, [] as ConceptIdT[]); + }, []); }; const ConceptTreeListItem = ({ From c238107cb2c1fc9213fb71da8b4ad591dacdd4cf Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 13:49:05 +0200 Subject: [PATCH 05/28] Use the same logic for list item and folder, cleanup --- .../js/concept-trees/ConceptTreeFolder.tsx | 55 +++++++++++++------ .../js/concept-trees/ConceptTreeListItem.tsx | 26 +++------ .../ConceptTreeNodeTextContainer.tsx | 32 +++++------ 3 files changed, 60 insertions(+), 53 deletions(-) diff --git a/frontend/src/js/concept-trees/ConceptTreeFolder.tsx b/frontend/src/js/concept-trees/ConceptTreeFolder.tsx index 6462d09643..0dd4c3571a 100644 --- a/frontend/src/js/concept-trees/ConceptTreeFolder.tsx +++ b/frontend/src/js/concept-trees/ConceptTreeFolder.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import { FC } from "react"; +import { useMemo } from "react"; import type { ConceptIdT, ConceptT } from "../api/types"; import { useOpenableConcept } from "../concept-trees-open/useOpenableConcept"; @@ -7,24 +7,13 @@ import { useOpenableConcept } from "../concept-trees-open/useOpenableConcept"; import ConceptTree from "./ConceptTree"; import ConceptTreeNodeTextContainer from "./ConceptTreeNodeTextContainer"; import { getConceptById } from "./globalTreeStoreHelper"; -import type { SearchT, TreesT } from "./reducer"; +import type { LoadedConcept, SearchT, TreesT } from "./reducer"; import { isNodeInSearchResult } from "./selectors"; const Root = styled("div")` font-size: ${({ theme }) => theme.font.sm}; `; -interface PropsT { - depth: number; - trees: TreesT; - tree: ConceptT; - conceptId: ConceptIdT; - active?: boolean; - openInitially?: boolean; - search: SearchT; - onLoadTree: (id: string) => void; -} - const sumMatchingEntities = (children: string[], initSum: number) => { return children.reduce((sum, treeId) => { const rootConcept = getConceptById(treeId); @@ -43,7 +32,22 @@ const sumMatchingEntries = (children: string[], initSum: number) => { }, initSum); }; -const ConceptTreeFolder: FC = ({ +export const getNonFolderChildren = ( + trees: TreesT, + node: LoadedConcept, +): string[] => { + if (node.detailsAvailable) return node.children || []; + + if (!node.children) return []; + + // collect all non-folder children, recursively + return node.children.reduce((acc, childId) => { + const child = trees[childId]; + return acc.concat(getNonFolderChildren(trees, child)); + }, []); +}; + +const ConceptTreeFolder = ({ trees, tree, conceptId, @@ -52,17 +56,32 @@ const ConceptTreeFolder: FC = ({ active, onLoadTree, openInitially, +}: { + depth: number; + trees: TreesT; + tree: ConceptT; + conceptId: ConceptIdT; + active?: boolean; + openInitially?: boolean; + search: SearchT; + onLoadTree: (id: string) => void; }) => { const { open, onToggleOpen } = useOpenableConcept({ conceptId, openInitially, }); - if (!search.showMismatches) { - const shouldRender = isNodeInSearchResult(conceptId, search, tree.children); + const nonFolderChildren = useMemo( + () => + tree.detailsAvailable ? tree.children : getNonFolderChildren(trees, tree), + [trees, tree], + ); - if (!shouldRender) return null; - } + if ( + !search.showMismatches && + !isNodeInSearchResult(conceptId, search, nonFolderChildren) + ) + return null; const matchingEntries = !tree.children || !tree.matchingEntries diff --git a/frontend/src/js/concept-trees/ConceptTreeListItem.tsx b/frontend/src/js/concept-trees/ConceptTreeListItem.tsx index ccf9174a8a..31a4d2f8c7 100644 --- a/frontend/src/js/concept-trees/ConceptTreeListItem.tsx +++ b/frontend/src/js/concept-trees/ConceptTreeListItem.tsx @@ -2,23 +2,11 @@ import { useMemo } from "react"; import type { ConceptIdT } from "../api/types"; import ConceptTree from "./ConceptTree"; -import ConceptTreeFolder from "./ConceptTreeFolder"; +import ConceptTreeFolder, { getNonFolderChildren } from "./ConceptTreeFolder"; import { getConceptById } from "./globalTreeStoreHelper"; -import type { LoadedConcept, SearchT, TreesT } from "./reducer"; +import type { SearchT, TreesT } from "./reducer"; import { isNodeInSearchResult } from "./selectors"; -const getNonFolderChildren = (trees: TreesT, node: LoadedConcept): string[] => { - if (node.detailsAvailable) return node.children || []; - - if (!node.children) return []; - - // collect all non-folder children, recursively - return node.children.reduce((acc, childId) => { - const child = trees[childId]; - return acc.concat(getNonFolderChildren(trees, child)); - }, []); -}; - const ConceptTreeListItem = ({ trees, conceptId, @@ -32,11 +20,11 @@ const ConceptTreeListItem = ({ }) => { const tree = trees[conceptId]; - const nonFolderChildren = useMemo(() => { - if (tree.detailsAvailable) return tree.children; - - return getNonFolderChildren(trees, tree); - }, [trees, tree]); + const nonFolderChildren = useMemo( + () => + tree.detailsAvailable ? tree.children : getNonFolderChildren(trees, tree), + [trees, tree], + ); if (!isNodeInSearchResult(conceptId, search, nonFolderChildren)) return null; diff --git a/frontend/src/js/concept-trees/ConceptTreeNodeTextContainer.tsx b/frontend/src/js/concept-trees/ConceptTreeNodeTextContainer.tsx index d951846f63..15007c2e03 100644 --- a/frontend/src/js/concept-trees/ConceptTreeNodeTextContainer.tsx +++ b/frontend/src/js/concept-trees/ConceptTreeNodeTextContainer.tsx @@ -1,4 +1,4 @@ -import { FC, useRef } from "react"; +import { useRef } from "react"; import { useDrag } from "react-dnd"; import type { ConceptIdT, ConceptT } from "../api/types"; @@ -15,19 +15,6 @@ import AdditionalInfoHoverable from "../tooltip/AdditionalInfoHoverable"; import ConceptTreeNodeText from "./ConceptTreeNodeText"; import type { SearchT } from "./reducer"; -interface PropsT { - conceptId: ConceptIdT; - node: ConceptT; - root: ConceptT; - open: boolean; - depth: number; - active?: boolean; - onTextClick?: () => void; - createQueryElement?: () => ConceptQueryNodeType; - search: SearchT; - isStructFolder?: boolean; -} - function getResultCount( search: SearchT, node: ConceptT, @@ -44,7 +31,7 @@ function getResultCount( : null; } -const ConceptTreeNodeTextContainer: FC = ({ +const ConceptTreeNodeTextContainer = ({ conceptId, node, root, @@ -55,11 +42,24 @@ const ConceptTreeNodeTextContainer: FC = ({ onTextClick, isStructFolder, createQueryElement, +}: { + conceptId: ConceptIdT; + node: ConceptT; + root: ConceptT; + open: boolean; + depth: number; + active?: boolean; + onTextClick?: () => void; + createQueryElement?: () => ConceptQueryNodeType; + search: SearchT; + isStructFolder?: boolean; }) => { const ref = useRef(null); const red = exists(node.matchingEntries) && node.matchingEntries === 0; - const resultCount = getResultCount(search, node, conceptId); + const resultCount = isStructFolder + ? null + : getResultCount(search, node, conceptId); const hasChildren = !!node.children && node.children.length > 0; const item: DragItemConceptTreeNode = { From a1940513d1c4776e410dd876cbf58ddfd7847da3 Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 14:38:36 +0200 Subject: [PATCH 06/28] Update non-critical minor versions for non-tooling dependencies --- frontend/package-lock.json | 192 ++++++++++++++++++++----------------- frontend/package.json | 34 +++---- 2 files changed, 119 insertions(+), 107 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 24e8a89e3f..3a99b6d260 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,19 +13,19 @@ "@emotion/is-prop-valid": "^1.2.1", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@fortawesome/fontawesome-svg-core": "^6.4.2", - "@fortawesome/free-regular-svg-icons": "^6.4.2", - "@fortawesome/free-solid-svg-icons": "^6.4.2", - "@fortawesome/react-fontawesome": "^0.2.0", + "@fortawesome/fontawesome-svg-core": "^6.6.0", + "@fortawesome/free-regular-svg-icons": "^6.6.0", + "@fortawesome/free-solid-svg-icons": "^6.6.0", + "@fortawesome/react-fontawesome": "^0.2.2", "@paralleldrive/cuid2": "^2.2.2", "@react-keycloak-fork/web": "^4.0.3", "@tippyjs/react": "^4.2.6", "@vitejs/plugin-react": "^4.1.1", "apache-arrow": "^13.0.0", "autoprefixer": "^10.4.19", - "axios": "^1.6.0", + "axios": "^1.7.7", "chance": "^1.1.11", - "chart.js": "^4.4.0", + "chart.js": "^4.4.4", "compression": "^1.7.4", "date-fns": "^2.30.0", "downshift": "^7.4.1", @@ -41,28 +41,28 @@ "nodemon": "^3.0.1", "postcss": "^8.4.38", "prettier-plugin-organize-imports": "^3.2.3", - "rc-table": "^7.35.2", - "react": "^18.2.0", + "rc-table": "^7.48.0", + "react": "^18.3.1", "react-chartjs-2": "^5.2.0", "react-datepicker": "^4.21.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dnd-multi-backend": "^8.0.3", "react-dnd-touch-backend": "^16.0.1", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-error-boundary": "^3.1.4", "react-highlight-words": "^0.20.0", - "react-hook-form": "^7.48.2", - "react-hotkeys-hook": "^4.4.1", + "react-hook-form": "^7.53.0", + "react-hotkeys-hook": "^4.5.1", "react-i18next": "^12.2.0", "react-list": "^0.8.16", "react-markdown": "^8.0.0", "react-merge-refs": "^2.1.1", - "react-number-format": "^5.3.1", + "react-number-format": "^5.4.2", "react-redux": "^8.1.3", "react-resizable-panels": "^0.0.55", - "react-router-dom": "^6.18.0", - "react-window": "^1.8.9", + "react-router-dom": "^6.26.2", + "react-window": "^1.8.10", "redux": "^4.1.2", "redux-devtools-extension": "^2.13.9", "remark-flexible-markers": "^1.0.3", @@ -95,13 +95,13 @@ "@types/mustache": "^4.2.4", "@types/node": "^18.15.3", "@types/papaparse": "^5.3.10", - "@types/react": "^18.2.79", + "@types/react": "^18.3.10", "@types/react-datepicker": "^4.19.1", - "@types/react-dom": "^18.2.14", + "@types/react-dom": "^18.3.0", "@types/react-highlight-words": "^0.16.6", "@types/react-list": "^0.8.9", "@types/react-router-dom": "^5.3.3", - "@types/react-window": "^1.8.7", + "@types/react-window": "^1.8.8", "@types/redux": "^3.6.0", "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", @@ -2410,49 +2410,50 @@ "license": "MIT" }, "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.4.2", - "hasInstallScript": true, - "license": "MIT", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", + "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==", "engines": { "node": ">=6" } }, "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.4.2", - "hasInstallScript": true, - "license": "MIT", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", + "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.2" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.4.2", - "hasInstallScript": true, - "license": "(CC-BY-4.0 AND MIT)", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz", + "integrity": "sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ==", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.2" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.4.2", - "hasInstallScript": true, - "license": "(CC-BY-4.0 AND MIT)", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz", + "integrity": "sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==", "dependencies": { - "@fortawesome/fontawesome-common-types": "6.4.2" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { "node": ">=6" } }, "node_modules/@fortawesome/react-fontawesome": { - "version": "0.2.0", - "license": "MIT", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", "dependencies": { "prop-types": "^15.8.1" }, @@ -3782,8 +3783,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.11.0", - "license": "MIT", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", + "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==", "engines": { "node": ">=14.0.0" } @@ -5833,9 +5835,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.2.79", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz", - "integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==", + "version": "18.3.10", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.10.tgz", + "integrity": "sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5853,9 +5855,10 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.14", + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", "devOptional": true, - "license": "MIT", "dependencies": { "@types/react": "*" } @@ -5896,9 +5899,10 @@ } }, "node_modules/@types/react-window": { - "version": "1.8.7", + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==", "dev": true, - "license": "MIT", "dependencies": { "@types/react": "*" } @@ -6584,10 +6588,11 @@ } }, "node_modules/axios": { - "version": "1.6.0", - "license": "MIT", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -7169,13 +7174,14 @@ } }, "node_modules/chart.js": { - "version": "4.4.0", - "license": "MIT", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", + "integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==", "dependencies": { "@kurkle/color": "^0.3.0" }, "engines": { - "pnpm": ">=7" + "pnpm": ">=8" } }, "node_modules/chokidar": { @@ -13423,16 +13429,16 @@ } }, "node_modules/rc-table": { - "version": "7.36.0", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.36.0.tgz", - "integrity": "sha512-3xVcdCC5OLeOOhaCg+5Lps2oPreM/GWXmUXWTSX4p6vF7F76ABM4dfPpMJ9Dnf5yGRyh+8pe7FRyhRVnWw2H/w==", + "version": "7.48.0", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.48.0.tgz", + "integrity": "sha512-LC0ojl/SYjeQa2eqBCvnbIFn/ebefkUm8TR67dTpuBo9t7ya0ucOPC9rMARjC4KeimyOGyOyCYlX++eg0Udk5g==", "dependencies": { "@babel/runtime": "^7.10.1", "@rc-component/context": "^1.4.0", "classnames": "^2.2.5", "rc-resize-observer": "^1.1.0", - "rc-util": "^5.37.0", - "rc-virtual-list": "^3.11.1" + "rc-util": "^5.41.0", + "rc-virtual-list": "^3.14.2" }, "engines": { "node": ">=8.x" @@ -13443,9 +13449,9 @@ } }, "node_modules/rc-util": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.1.tgz", - "integrity": "sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.43.0.tgz", + "integrity": "sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==", "dependencies": { "@babel/runtime": "^7.18.3", "react-is": "^18.2.0" @@ -13456,9 +13462,9 @@ } }, "node_modules/rc-virtual-list": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.11.3.tgz", - "integrity": "sha512-tu5UtrMk/AXonHwHxUogdXAWynaXsrx1i6dsgg+lOo/KJSF8oBAcprh1z5J3xgnPJD5hXxTL58F8s8onokdt0Q==", + "version": "3.14.8", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.14.8.tgz", + "integrity": "sha512-8D0KfzpRYi6YZvlOWIxiOm9BGt4Wf2hQyEaM6RXlDDiY2NhLheuYI+RA+7ZaZj1lq+XQqy3KHlaeeXQfzI5fGg==", "dependencies": { "@babel/runtime": "^7.20.0", "classnames": "^2.2.6", @@ -13469,13 +13475,14 @@ "node": ">=8.x" }, "peerDependencies": { - "react": "*", - "react-dom": "*" + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, "node_modules/react": { - "version": "18.2.0", - "license": "MIT", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -13623,14 +13630,15 @@ "license": "MIT" }, "node_modules/react-dom": { - "version": "18.2.0", - "license": "MIT", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/react-element-to-jsx-string": { @@ -13687,22 +13695,24 @@ "license": "MIT" }, "node_modules/react-hook-form": { - "version": "7.48.2", - "license": "MIT", + "version": "7.53.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.0.tgz", + "integrity": "sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==", "engines": { - "node": ">=12.22.0" + "node": ">=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/react-hook-form" }, "peerDependencies": { - "react": "^16.8.0 || ^17 || ^18" + "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "node_modules/react-hotkeys-hook": { - "version": "4.4.1", - "license": "MIT", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/react-hotkeys-hook/-/react-hotkeys-hook-4.5.1.tgz", + "integrity": "sha512-scAEJOh3Irm0g95NIn6+tQVf/OICCjsQsC9NBHfQws/Vxw4sfq1tDQut5fhTEvPraXhu/sHxRd9lOtxzyYuNAg==", "peerDependencies": { "react": ">=16.8.1", "react-dom": ">=16.8.1" @@ -13788,11 +13798,9 @@ } }, "node_modules/react-number-format": { - "version": "5.3.1", - "license": "MIT", - "dependencies": { - "prop-types": "^15.7.2" - }, + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-5.4.2.tgz", + "integrity": "sha512-cg//jVdS49PYDgmcYoBnMMHl4XNTMuV723ZnHD2aXYtWWWqbVF3hjQ8iB+UZEuXapLbeA8P8H+1o6ZB1lcw3vg==", "peerDependencies": { "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" @@ -13922,10 +13930,11 @@ } }, "node_modules/react-router": { - "version": "6.18.0", - "license": "MIT", + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.2.tgz", + "integrity": "sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==", "dependencies": { - "@remix-run/router": "1.11.0" + "@remix-run/router": "1.19.2" }, "engines": { "node": ">=14.0.0" @@ -13935,11 +13944,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.18.0", - "license": "MIT", + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.2.tgz", + "integrity": "sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==", "dependencies": { - "@remix-run/router": "1.11.0", - "react-router": "6.18.0" + "@remix-run/router": "1.19.2", + "react-router": "6.26.2" }, "engines": { "node": ">=14.0.0" @@ -13972,8 +13982,9 @@ } }, "node_modules/react-window": { - "version": "1.8.9", - "license": "MIT", + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", + "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==", "dependencies": { "@babel/runtime": "^7.0.0", "memoize-one": ">=3.1.1 <6" @@ -14572,8 +14583,9 @@ } }, "node_modules/scheduler": { - "version": "0.23.0", - "license": "MIT", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } diff --git a/frontend/package.json b/frontend/package.json index 0d165804c0..7eeef43a04 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,19 +27,19 @@ "@emotion/is-prop-valid": "^1.2.1", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@fortawesome/fontawesome-svg-core": "^6.4.2", - "@fortawesome/free-regular-svg-icons": "^6.4.2", - "@fortawesome/free-solid-svg-icons": "^6.4.2", - "@fortawesome/react-fontawesome": "^0.2.0", + "@fortawesome/fontawesome-svg-core": "^6.6.0", + "@fortawesome/free-regular-svg-icons": "^6.6.0", + "@fortawesome/free-solid-svg-icons": "^6.6.0", + "@fortawesome/react-fontawesome": "^0.2.2", "@paralleldrive/cuid2": "^2.2.2", "@react-keycloak-fork/web": "^4.0.3", "@tippyjs/react": "^4.2.6", "@vitejs/plugin-react": "^4.1.1", "apache-arrow": "^13.0.0", "autoprefixer": "^10.4.19", - "axios": "^1.6.0", + "axios": "^1.7.7", "chance": "^1.1.11", - "chart.js": "^4.4.0", + "chart.js": "^4.4.4", "compression": "^1.7.4", "date-fns": "^2.30.0", "downshift": "^7.4.1", @@ -55,28 +55,28 @@ "nodemon": "^3.0.1", "postcss": "^8.4.38", "prettier-plugin-organize-imports": "^3.2.3", - "rc-table": "^7.35.2", - "react": "^18.2.0", + "rc-table": "^7.48.0", + "react": "^18.3.1", "react-chartjs-2": "^5.2.0", "react-datepicker": "^4.21.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dnd-multi-backend": "^8.0.3", "react-dnd-touch-backend": "^16.0.1", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-error-boundary": "^3.1.4", "react-highlight-words": "^0.20.0", - "react-hook-form": "^7.48.2", - "react-hotkeys-hook": "^4.4.1", + "react-hook-form": "^7.53.0", + "react-hotkeys-hook": "^4.5.1", "react-i18next": "^12.2.0", "react-list": "^0.8.16", "react-markdown": "^8.0.0", "react-merge-refs": "^2.1.1", - "react-number-format": "^5.3.1", + "react-number-format": "^5.4.2", "react-redux": "^8.1.3", "react-resizable-panels": "^0.0.55", - "react-router-dom": "^6.18.0", - "react-window": "^1.8.9", + "react-router-dom": "^6.26.2", + "react-window": "^1.8.10", "redux": "^4.1.2", "redux-devtools-extension": "^2.13.9", "remark-flexible-markers": "^1.0.3", @@ -109,13 +109,13 @@ "@types/mustache": "^4.2.4", "@types/node": "^18.15.3", "@types/papaparse": "^5.3.10", - "@types/react": "^18.2.79", + "@types/react": "^18.3.10", "@types/react-datepicker": "^4.19.1", - "@types/react-dom": "^18.2.14", + "@types/react-dom": "^18.3.0", "@types/react-highlight-words": "^0.16.6", "@types/react-list": "^0.8.9", "@types/react-router-dom": "^5.3.3", - "@types/react-window": "^1.8.7", + "@types/react-window": "^1.8.8", "@types/redux": "^3.6.0", "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", From b1678b5e903f36f255c8617839507e06f62981e0 Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 15:13:20 +0200 Subject: [PATCH 07/28] Fix defaultParams resetting also when clicking reset in history navigation --- frontend/src/js/dataset/actions.ts | 2 +- frontend/src/js/entity-history/Navigation.tsx | 2 +- frontend/src/js/entity-history/actions.ts | 4 +++- frontend/src/js/entity-history/reducer.ts | 6 +++++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/frontend/src/js/dataset/actions.ts b/frontend/src/js/dataset/actions.ts index f0f8b27f77..fb127723c1 100644 --- a/frontend/src/js/dataset/actions.ts +++ b/frontend/src/js/dataset/actions.ts @@ -112,7 +112,7 @@ export const useSelectDataset = () => { dispatch(selectDatasetInput({ id: datasetId })); - dispatch(resetHistory()); + dispatch(resetHistory({ includingDefaultParams: true })); dispatch(queryResultReset({ queryType: "standard" })); dispatch(queryResultReset({ queryType: "timebased" })); dispatch(queryResultReset({ queryType: "editorV2" })); diff --git a/frontend/src/js/entity-history/Navigation.tsx b/frontend/src/js/entity-history/Navigation.tsx index 3b7139feee..8043d3d65e 100644 --- a/frontend/src/js/entity-history/Navigation.tsx +++ b/frontend/src/js/entity-history/Navigation.tsx @@ -133,7 +133,7 @@ export const Navigation = memo( const onReset = useCallback(() => { onResetHistory(); - dispatch(resetHistory()); + dispatch(resetHistory({ includingDefaultParams: false })); }, [dispatch, onResetHistory]); useHotkeys("shift+up", goToPrev, [goToPrev]); diff --git a/frontend/src/js/entity-history/actions.ts b/frontend/src/js/entity-history/actions.ts index f237e8d6cc..e96338535f 100644 --- a/frontend/src/js/entity-history/actions.ts +++ b/frontend/src/js/entity-history/actions.ts @@ -82,7 +82,9 @@ export const useLoadDefaultHistoryParams = () => { export const resetCurrentEntity = createAction( "history/RESET_CURRENT_ENTITY", )(); -export const resetHistory = createAction("history/RESET")(); +export const resetHistory = createAction("history/RESET")<{ + includingDefaultParams?: boolean; +}>(); export const loadHistoryData = createAsyncAction( "history/LOAD_START", diff --git a/frontend/src/js/entity-history/reducer.ts b/frontend/src/js/entity-history/reducer.ts index f34b67cb05..16f94c0594 100644 --- a/frontend/src/js/entity-history/reducer.ts +++ b/frontend/src/js/entity-history/reducer.ts @@ -113,7 +113,11 @@ export default function reducer( case getType(resetHistory): return { ...state, - defaultParams: initialState.defaultParams, + ...(action.payload.includingDefaultParams + ? { + defaultParams: initialState.defaultParams, + } + : {}), label: "", columns: {}, columnDescriptions: [], From 3fa1b2a3cb2aca8961258fc3af887b8cc0e18d59 Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 16:51:06 +0200 Subject: [PATCH 08/28] Update vite and storybook dependencies, update stories --- frontend/.storybook/main.cjs | 25 - frontend/.storybook/main.ts | 18 + frontend/.storybook/manager.js | 5 + frontend/.storybook/preview.tsx | 36 +- frontend/package-lock.json | 9557 ++++++----------- frontend/package.json | 20 +- .../src/js/symbols/FormSymbol.stories.tsx | 14 +- .../src/js/symbols/QuerySymbol.stories.tsx | 15 +- .../InputMultiSelect.stories.tsx | 48 +- .../InputPlain/InputPlain.stories.tsx | 58 +- .../InputSelect/InputSelect.stories.tsx | 34 +- frontend/tsconfig.json | 7 +- 12 files changed, 3173 insertions(+), 6664 deletions(-) delete mode 100644 frontend/.storybook/main.cjs create mode 100644 frontend/.storybook/main.ts create mode 100644 frontend/.storybook/manager.js diff --git a/frontend/.storybook/main.cjs b/frontend/.storybook/main.cjs deleted file mode 100644 index 6eba201346..0000000000 --- a/frontend/.storybook/main.cjs +++ /dev/null @@ -1,25 +0,0 @@ -const path = require("path"); -const { mergeConfig } = require("vite"); -const toPath = (_path) => path.resolve(path.join(__dirname, _path)); - -module.exports = { - stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], - addons: [ - "@storybook/addon-links", - "@storybook/addon-essentials", - "@storybook/addon-interactions", - ], - framework: { - name: "@storybook/react-vite", - options: {}, - }, - features: { - storyStoreV7: true, - }, - core: { - disableTelemetry: true, - }, - docs: { - autodocs: true, - }, -}; diff --git a/frontend/.storybook/main.ts b/frontend/.storybook/main.ts new file mode 100644 index 0000000000..5329599c30 --- /dev/null +++ b/frontend/.storybook/main.ts @@ -0,0 +1,18 @@ +import type { StorybookConfig } from "@storybook/react-vite"; + +const config: StorybookConfig = { + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-interactions", + ], + framework: { + name: "@storybook/react-vite", + options: {}, + }, + core: { + disableTelemetry: true, + }, +}; +export default config; diff --git a/frontend/.storybook/manager.js b/frontend/.storybook/manager.js new file mode 100644 index 0000000000..5128367956 --- /dev/null +++ b/frontend/.storybook/manager.js @@ -0,0 +1,5 @@ +import { addons } from "@storybook/manager-api"; + +addons.setConfig({ + panelPosition: "right", +}); diff --git a/frontend/.storybook/preview.tsx b/frontend/.storybook/preview.tsx index 4b56d0c0aa..90e7ef34a3 100644 --- a/frontend/.storybook/preview.tsx +++ b/frontend/.storybook/preview.tsx @@ -1,4 +1,5 @@ import { ThemeProvider } from "@emotion/react"; +import type { Preview } from "@storybook/react"; import { theme } from "../src/app-theme"; import GlobalStyles from "../src/js/GlobalStyles"; @@ -9,23 +10,26 @@ import translationsDe from "../src/localization/de.json"; i18next.addResourceBundle("de", "translation", translationsDe, true, true); i18next.changeLanguage("de"); -export const parameters = { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, +const Decorator = (Story: any) => ( + + + + + + +); + +const preview: Preview = { + decorators: [Decorator], + parameters: { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, }, }, }; -export const decorators = [ - (Story) => ( - - - - - - - ), -]; +export default preview; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3a99b6d260..7c3e355e2c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -20,8 +20,8 @@ "@paralleldrive/cuid2": "^2.2.2", "@react-keycloak-fork/web": "^4.0.3", "@tippyjs/react": "^4.2.6", - "@vitejs/plugin-react": "^4.1.1", - "apache-arrow": "^13.0.0", + "@vitejs/plugin-react": "^4.3.2", + "apache-arrow": "^17.0.0", "autoprefixer": "^10.4.19", "axios": "^1.7.7", "chance": "^1.1.11", @@ -70,16 +70,16 @@ "resize-observer-polyfill": "^1.5.1", "tailwindcss": "^3.4.3", "typesafe-actions": "^5.1.0", - "vite": "^4.5.0" + "vite": "^5.4.8" }, "devDependencies": { "@babel/core": "^7.23.2", - "@storybook/addon-actions": "7.5.3", - "@storybook/addon-essentials": "7.5.3", - "@storybook/addon-interactions": "7.5.3", - "@storybook/addon-links": "7.5.3", - "@storybook/react": "7.5.3", - "@storybook/react-vite": "7.5.3", + "@storybook/addon-actions": "8.3.4", + "@storybook/addon-essentials": "8.3.4", + "@storybook/addon-interactions": "8.3.4", + "@storybook/addon-links": "8.3.4", + "@storybook/react": "8.3.4", + "@storybook/react-vite": "8.3.4", "@storybook/testing-library": "^0.2.2", "@swc/core": "^1.3.96", "@testing-library/react": "^14.0.0", @@ -114,7 +114,7 @@ "jest-environment-jsdom": "^29.7.0", "papaparse": "^5.4.1", "prettier": "^3.0.3", - "storybook": "7.5.3", + "storybook": "8.3.4", "tailwind-styled-components": "^2.2.0", "terser": "^5.24.0", "ts-jest": "^29.1.1", @@ -153,6 +153,12 @@ "node": ">=0.10.0" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", + "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==", + "dev": true + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -175,89 +181,41 @@ "node": ">=6.0.0" } }, - "node_modules/@aw-web-design/x-default-browser": { - "version": "1.4.126", - "dev": true, - "license": "MIT", - "dependencies": { - "default-browser-id": "3.0.0" - }, - "bin": { - "x-default-browser": "bin/x-default-browser.js" - } - }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "license": "MIT" - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@babel/compat-data": { - "version": "7.23.2", - "license": "MIT", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.2", - "license": "MIT", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.0", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -280,47 +238,27 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.0", - "license": "MIT", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "license": "MIT", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -330,149 +268,41 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { "version": "5.1.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "license": "ISC" - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.15", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.0", - "license": "MIT", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -481,140 +311,71 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "license": "MIT", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" - }, + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.2", - "license": "MIT", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.2", - "@babel/types": "^7.23.0" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "license": "MIT", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -622,7 +383,8 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { "color-convert": "^1.9.0" }, @@ -632,7 +394,8 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -644,25 +407,32 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/parser": { - "version": "7.23.0", - "license": "MIT", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -670,211 +440,46 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.15", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.15", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { - "@babel/core": "^7.13.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -971,20 +576,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "dev": true, @@ -1013,27 +604,26 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "dev": true, - "license": "MIT", + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz", + "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.22.5", - "dev": true, - "license": "MIT", + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz", + "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1042,985 +632,822 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-generator-functions": { + "node_modules/@babel/runtime": { "version": "7.23.2", - "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.22.5", - "dev": true, - "license": "MIT", + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dependencies": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "node_modules/@babel/traverse": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", + "debug": "^4.3.1", + "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.0", - "dev": true, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=4" } }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.22.5", - "dev": true, - "license": "MIT", + "node_modules/@babel/types": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.22.11", + "node_modules/@base2/pretty-print-object": { + "version": "1.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.11", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } + "license": "BSD-2-Clause" }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.15", - "dev": true, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "devOptional": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" + "@jridgewell/trace-mapping": "0.3.9" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes/node_modules/globals": { - "version": "11.12.0", - "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.22.5", - "dev": true, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "devOptional": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.0", - "dev": true, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "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.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "license": "MIT" + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "license": "BSD-3-Clause", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.10.0" } }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.22.5", - "dev": true, + "node_modules/@emotion/cache": { + "version": "11.11.0", "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.22.5", - "dev": true, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@emotion/memoize": "^0.8.1" } }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.22.11", - "dev": true, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.22.5", - "dev": true, + "node_modules/@emotion/serialize": { + "version": "1.1.2", "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" } }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.22.11", - "dev": true, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.22.5", - "dev": true, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-flow": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "react": ">=16.8.0" } }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.15", + "node_modules/@emotion/utils": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.22.5", + "node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.22.11", + "node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.22.5", + "node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.11", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.22.5", + "node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.0", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.0", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.0", + "node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.22.5", + "node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", + "node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.22.5", + "node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.11", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.22.11", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.15", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.15" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.22.5", + "node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.11", + "node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.0", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.15", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.22.5", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.22.11", + "node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.11", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.22.5", + "node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.22.5", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.22.5", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.22.10", - "dev": true, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.2" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.22.5", - "dev": true, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.22.5", - "dev": true, + "node_modules/@eslint/eslintrc": { + "version": "2.1.3", "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.22.5", - "dev": true, + "node_modules/@eslint/js": { + "version": "8.53.0", "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", + "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.22.5", - "dev": true, - "license": "MIT", + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", + "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.22.5", - "dev": true, - "license": "MIT", + "node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz", + "integrity": "sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.22.15", - "dev": true, - "license": "MIT", + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz", + "integrity": "sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.22.5" + "@fortawesome/fontawesome-common-types": "6.6.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.22.10", - "dev": true, - "license": "MIT", + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" + "prop-types": "^15.8.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" } }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.22.5", - "dev": true, - "license": "MIT", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=10.10.0" } }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": ">=12.22" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "license": "BSD-3-Clause" }, - "node_modules/@babel/preset-env": { - "version": "7.23.2", - "dev": true, - "license": "MIT", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "license": "ISC", "dependencies": { - "@babel/compat-data": "^7.23.2", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@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.22.5", - "@babel/plugin-syntax-import-attributes": "^7.22.5", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@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", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.23.2", - "@babel/plugin-transform-async-to-generator": "^7.22.5", - "@babel/plugin-transform-block-scoped-functions": "^7.22.5", - "@babel/plugin-transform-block-scoping": "^7.23.0", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.11", - "@babel/plugin-transform-classes": "^7.22.15", - "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.23.0", - "@babel/plugin-transform-dotall-regex": "^7.22.5", - "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.11", - "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.11", - "@babel/plugin-transform-for-of": "^7.22.15", - "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.11", - "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", - "@babel/plugin-transform-member-expression-literals": "^7.22.5", - "@babel/plugin-transform-modules-amd": "^7.23.0", - "@babel/plugin-transform-modules-commonjs": "^7.23.0", - "@babel/plugin-transform-modules-systemjs": "^7.23.0", - "@babel/plugin-transform-modules-umd": "^7.22.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.22.5", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", - "@babel/plugin-transform-numeric-separator": "^7.22.11", - "@babel/plugin-transform-object-rest-spread": "^7.22.15", - "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.11", - "@babel/plugin-transform-optional-chaining": "^7.23.0", - "@babel/plugin-transform-parameters": "^7.22.15", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.11", - "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.10", - "@babel/plugin-transform-reserved-words": "^7.22.5", - "@babel/plugin-transform-shorthand-properties": "^7.22.5", - "@babel/plugin-transform-spread": "^7.22.5", - "@babel/plugin-transform-sticky-regex": "^7.22.5", - "@babel/plugin-transform-template-literals": "^7.22.5", - "@babel/plugin-transform-typeof-symbol": "^7.22.5", - "@babel/plugin-transform-unicode-escapes": "^7.22.10", - "@babel/plugin-transform-unicode-property-regex": "^7.22.5", - "@babel/plugin-transform-unicode-regex": "^7.22.5", - "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "@babel/types": "^7.23.0", - "babel-plugin-polyfill-corejs2": "^0.4.6", - "babel-plugin-polyfill-corejs3": "^0.8.5", - "babel-plugin-polyfill-regenerator": "^0.5.3", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=12" } }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", "dev": true, "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-flow": { - "version": "7.22.15", - "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-transform-flow-strip-types": "^7.22.5" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + "node": ">=8" } }, - "node_modules/@babel/preset-typescript": { - "version": "7.23.2", + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.23.0", - "@babel/plugin-transform-typescript": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "sprintf-js": "~1.0.2" } }, - "node_modules/@babel/register": { - "version": "7.22.15", + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", "dev": true, "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "find-cache-dir": "^2.0.0", - "make-dir": "^2.1.0", - "pirates": "^4.0.5", - "source-map-support": "^0.5.16" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6" } }, - "node_modules/@babel/register/node_modules/find-cache-dir": { - "version": "2.1.0", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", "dev": true, "license": "MIT", "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@babel/register/node_modules/find-up": { - "version": "3.0.0", + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^3.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": ">=6" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@babel/register/node_modules/locate-path": { - "version": "3.0.0", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@babel/register/node_modules/p-limit": { + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", "dev": true, "license": "MIT", @@ -2034,2966 +1461,1333 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/register/node_modules/p-locate": { - "version": "3.0.0", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@babel/register/node_modules/path-exists": { - "version": "3.0.0", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/@babel/register/node_modules/pkg-dir": { - "version": "3.0.0", + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, - "license": "MIT", "dependencies": { - "find-up": "^3.0.0" + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, - "license": "MIT" - }, - "node_modules/@babel/runtime": { - "version": "7.23.2", - "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.14.0" + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@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.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@babel/template": { - "version": "7.22.15", - "license": "MIT", + "node_modules/@jest/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, - "node_modules/@babel/traverse": { - "version": "7.23.2", - "license": "MIT", + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", - "globals": "^11.1.0" + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" }, "engines": { - "node": ">=6.9.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "license": "MIT", + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, "engines": { - "node": ">=4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@babel/types": { - "version": "7.23.0", - "license": "MIT", + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "jest-get-type": "^29.6.3" }, "engines": { - "node": ">=6.9.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@base2/pretty-print-object": { - "version": "1.0.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@colors/colors": { - "version": "1.5.0", + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, - "license": "MIT", - "optional": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, "engines": { - "node": ">=0.1.90" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "devOptional": true, - "license": "MIT", + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { - "node": ">=12" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "devOptional": true, - "license": "MIT", + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", + "node_modules/@jest/reporters/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=10.0.0" + "node": ">=8" } }, - "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", + "node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", - "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.2.0" + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { - "version": "1.9.0", - "license": "MIT" - }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "license": "BSD-3-Clause", + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@emotion/cache": { - "version": "11.11.0", - "license": "MIT", - "dependencies": { - "@emotion/memoize": "^0.8.1", - "@emotion/sheet": "^1.2.2", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "stylis": "4.2.0" + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@emotion/hash": { - "version": "0.9.1", - "license": "MIT" + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.1", + "node_modules/@jest/transform": { + "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { - "@emotion/memoize": "^0.8.1" + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@emotion/memoize": { - "version": "0.8.1", - "license": "MIT" + "node_modules/@jest/transform/node_modules/write-file-atomic": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "node_modules/@emotion/react": { - "version": "11.11.1", + "node_modules/@jest/types": { + "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.2", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@emotion/serialize": { - "version": "1.1.2", + "node_modules/@jest/types/node_modules/@types/node": { + "version": "20.8.10", + "dev": true, "license": "MIT", "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", - "csstype": "^3.0.2" + "undici-types": "~5.26.4" } }, - "node_modules/@emotion/sheet": { - "version": "1.2.2", - "license": "MIT" - }, - "node_modules/@emotion/styled": { - "version": "11.11.0", + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { + "version": "0.3.0", + "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/is-prop-valid": "^1.2.1", - "@emotion/serialize": "^1.1.2", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1" + "glob": "^7.2.0", + "glob-promise": "^4.2.0", + "magic-string": "^0.27.0", + "react-docgen-typescript": "^2.2.2" }, "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" + "typescript": ">= 4.3.x", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { - "@types/react": { + "typescript": { "optional": true } } }, - "node_modules/@emotion/unitless": { - "version": "0.8.1", - "license": "MIT" + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.1", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@emotion/utils": { + "node_modules/@jridgewell/set-array": { "version": "1.2.1", - "license": "MIT" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "license": "MIT" - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { - "node": ">=12" + "node": ">=6.0.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "devOptional": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@kurkle/color": { + "version": "0.3.2", + "license": "MIT" + }, + "node_modules/@mdx-js/react": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", + "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", + "dev": true, + "dependencies": { + "@types/mdx": "^2.0.0" }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "@types/react": ">=16", + "react": ">=16" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", + "node_modules/@noble/hashes": { + "version": "1.3.2", "license": "MIT", "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.3", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", "license": "MIT", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 8" } }, - "node_modules/@eslint/js": { - "version": "8.53.0", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 8" } }, - "node_modules/@fal-works/esbuild-plugin-global-externals": { - "version": "2.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@floating-ui/core": { - "version": "1.5.0", - "dev": true, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.1.3" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.4.2", - "@floating-ui/utils": "^0.1.3" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.5.1" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz", - "integrity": "sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz", - "integrity": "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg==", - "dependencies": { - "@fortawesome/fontawesome-common-types": "6.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz", - "integrity": "sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ==", - "dependencies": { - "@fortawesome/fontawesome-common-types": "6.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz", - "integrity": "sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA==", - "dependencies": { - "@fortawesome/fontawesome-common-types": "6.6.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=6" + "node": ">= 8" } }, - "node_modules/@fortawesome/react-fontawesome": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", - "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.2", + "license": "MIT", "dependencies": { - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "@fortawesome/fontawesome-svg-core": "~1 || ~6", - "react": ">=16.3" + "@noble/hashes": "^1.1.5" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "license": "MIT", + "optional": true, "engines": { - "node": ">=10.10.0" + "node": ">=14" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "license": "MIT", "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "type": "opencollective", + "url": "https://opencollective.com/popperjs" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "license": "BSD-3-Clause" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "license": "ISC", + "node_modules/@rc-component/context": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", + "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==", "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "@babel/runtime": "^7.10.1", + "rc-util": "^5.27.0" }, - "engines": { - "node": ">=12" + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/@react-dnd/asap": { + "version": "5.0.2", + "license": "MIT" }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "node_modules/@react-dnd/invariant": { + "version": "4.0.2", + "license": "MIT" }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } + "node_modules/@react-dnd/shallowequal": { + "version": "4.0.2", + "license": "MIT" }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "dev": true, + "node_modules/@react-keycloak-fork/core": { + "version": "4.0.3", "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "react-fast-compare": "^3.2.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/reactkeycloak" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "peerDependencies": { + "react": ">=16" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, + "node_modules/@react-keycloak-fork/web": { + "version": "4.0.3", "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "@babel/runtime": "^7.17.9", + "@react-keycloak-fork/core": "^4.0.3", + "hoist-non-react-statics": "^3.3.2" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/reactkeycloak" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "keycloak-js": ">=17.0.0", + "react": ">=16.0", + "react-dom": ">=16.0", + "typescript": ">=3.8" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, + "node_modules/@remix-run/router": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", + "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==", "engines": { - "node": ">=8" + "node": ">=14.0.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 8.0.0" } }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@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.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform/node_modules/write-file-atomic": { - "version": "4.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types/node_modules/@types/node": { - "version": "20.8.10", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "glob": "^7.2.0", - "glob-promise": "^4.2.0", - "magic-string": "^0.27.0", - "react-docgen-typescript": "^2.2.2" - }, - "peerDependencies": { - "typescript": ">= 4.3.x", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@juggle/resize-observer": { - "version": "3.4.0", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@kurkle/color": { - "version": "0.3.2", - "license": "MIT" - }, - "node_modules/@mdx-js/react": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mdx": "^2.0.0", - "@types/react": ">=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "react": ">=16" - } - }, - "node_modules/@ndelangen/get-tarball": { - "version": "3.0.9", - "dev": true, - "license": "MIT", - "dependencies": { - "gunzip-maybe": "^1.4.2", - "pump": "^3.0.0", - "tar-fs": "^2.1.1" - } - }, - "node_modules/@noble/hashes": { - "version": "1.3.2", - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@paralleldrive/cuid2": { - "version": "2.2.2", - "license": "MIT", - "dependencies": { - "@noble/hashes": "^1.1.5" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@radix-ui/number": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/primitive": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-escape-keydown": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popper": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-rect": "1.0.1", - "@radix-ui/react-use-size": "1.0.1", - "@radix-ui/rect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-select": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/number": "1.0.1", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.4", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.3", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.2", - "@radix-ui/react-portal": "1.0.3", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-separator": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-toggle": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toolbar": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-separator": "1.0.3", - "@radix-ui/react-toggle-group": "1.0.4" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-previous": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-rect": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/rect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/rect": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@rc-component/context": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", - "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==", - "dependencies": { - "@babel/runtime": "^7.10.1", - "rc-util": "^5.27.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@react-dnd/asap": { - "version": "5.0.2", - "license": "MIT" - }, - "node_modules/@react-dnd/invariant": { - "version": "4.0.2", - "license": "MIT" - }, - "node_modules/@react-dnd/shallowequal": { - "version": "4.0.2", - "license": "MIT" - }, - "node_modules/@react-keycloak-fork/core": { - "version": "4.0.3", - "license": "MIT", - "dependencies": { - "react-fast-compare": "^3.2.0" - }, - "funding": { - "type": "patreon", - "url": "https://www.patreon.com/reactkeycloak" - }, - "peerDependencies": { - "react": ">=16" - } - }, - "node_modules/@react-keycloak-fork/web": { - "version": "4.0.3", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.17.9", - "@react-keycloak-fork/core": "^4.0.3", - "hoist-non-react-statics": "^3.3.2" - }, - "funding": { - "type": "patreon", - "url": "https://www.patreon.com/reactkeycloak" - }, - "peerDependencies": { - "keycloak-js": ">=17.0.0", - "react": ">=16.0", - "react-dom": ">=16.0", - "typescript": ">=3.8" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@remix-run/router": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", - "integrity": "sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@storybook/addon-actions": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "polished": "^4.2.2", - "prop-types": "^15.7.2", - "react-inspector": "^6.0.0", - "telejson": "^7.2.0", - "ts-dedent": "^2.0.0", - "uuid": "^9.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-backgrounds": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "memoizerific": "^1.11.3", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-controls": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/blocks": "7.5.3", - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-common": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/manager-api": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "lodash": "^4.17.21", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-docs": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.3.1", - "@mdx-js/react": "^2.1.5", - "@storybook/blocks": "7.5.3", - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/csf-plugin": "7.5.3", - "@storybook/csf-tools": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/mdx2-csf": "^1.0.0", - "@storybook/node-logger": "7.5.3", - "@storybook/postinstall": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/react-dom-shim": "7.5.3", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "fs-extra": "^11.1.0", - "remark-external-links": "^8.0.0", - "remark-slug": "^6.0.0", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/addon-essentials": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/addon-actions": "7.5.3", - "@storybook/addon-backgrounds": "7.5.3", - "@storybook/addon-controls": "7.5.3", - "@storybook/addon-docs": "7.5.3", - "@storybook/addon-highlight": "7.5.3", - "@storybook/addon-measure": "7.5.3", - "@storybook/addon-outline": "7.5.3", - "@storybook/addon-toolbars": "7.5.3", - "@storybook/addon-viewport": "7.5.3", - "@storybook/core-common": "7.5.3", - "@storybook/manager-api": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@storybook/preview-api": "7.5.3", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/addon-highlight": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.5.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addon-interactions": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-common": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "7.5.3", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "jest-mock": "^27.0.6", - "polished": "^4.2.2", - "ts-dedent": "^2.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/@storybook/addon-interactions/node_modules/@jest/types": { - "version": "27.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@storybook/addon-interactions/node_modules/@types/node": { - "version": "20.8.10", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@storybook/addon-interactions/node_modules/@types/yargs": { - "version": "16.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@storybook/addon-interactions/node_modules/jest-mock": { - "version": "27.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@storybook/addon-links": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/csf": "^0.1.0", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/router": "7.5.3", - "@storybook/types": "7.5.3", - "prop-types": "^15.7.2", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/addon-measure": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/types": "7.5.3", - "tiny-invariant": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/addon-outline": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/types": "7.5.3", - "ts-dedent": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/addon-toolbars": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/theming": "7.5.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/addon-viewport": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/theming": "7.5.3", - "memoizerific": "^1.11.3", - "prop-types": "^15.7.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/blocks": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/channels": "7.5.3", - "@storybook/client-logger": "7.5.3", - "@storybook/components": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/csf": "^0.1.0", - "@storybook/docs-tools": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "@types/lodash": "^4.14.167", - "color-convert": "^2.0.1", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "markdown-to-jsx": "^7.1.8", - "memoizerific": "^1.11.3", - "polished": "^4.2.2", - "react-colorful": "^5.1.2", - "telejson": "^7.2.0", - "tocbot": "^4.20.1", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/builder-manager": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "7.5.3", - "@storybook/manager": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@types/ejs": "^3.1.1", - "@types/find-cache-dir": "^3.2.1", - "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", - "browser-assert": "^1.2.1", - "ejs": "^3.1.8", - "esbuild": "^0.18.0", - "esbuild-plugin-alias": "^0.2.1", - "express": "^4.17.3", - "find-cache-dir": "^3.0.0", - "fs-extra": "^11.1.0", - "process": "^0.11.10", - "util": "^0.12.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/builder-vite": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/channels": "7.5.3", - "@storybook/client-logger": "7.5.3", - "@storybook/core-common": "7.5.3", - "@storybook/csf-plugin": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@storybook/preview": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/types": "7.5.3", - "@types/find-cache-dir": "^3.2.1", - "browser-assert": "^1.2.1", - "es-module-lexer": "^0.9.3", - "express": "^4.17.3", - "find-cache-dir": "^3.0.0", - "fs-extra": "^11.1.0", - "magic-string": "^0.30.0", - "rollup": "^2.25.0 || ^3.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "@preact/preset-vite": "*", - "typescript": ">= 4.3.x", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0", - "vite-plugin-glimmerx": "*" - }, - "peerDependenciesMeta": { - "@preact/preset-vite": { - "optional": true - }, - "typescript": { - "optional": true - }, - "vite-plugin-glimmerx": { - "optional": true - } - } + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/builder-vite/node_modules/es-module-lexer": { - "version": "0.9.3", - "dev": true, - "license": "MIT" + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@storybook/builder-vite/node_modules/magic-string": { - "version": "0.30.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@storybook/channels": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "qs": "^6.10.0", - "telejson": "^7.2.0", - "tiny-invariant": "^1.3.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@storybook/channels/node_modules/qs": { - "version": "6.11.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@storybook/cli": { - "version": "7.5.3", + "node_modules/@sinclair/typebox": { + "version": "0.27.8", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/types": "^7.22.5", - "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "7.5.3", - "@storybook/core-common": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/core-server": "7.5.3", - "@storybook/csf-tools": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@storybook/telemetry": "7.5.3", - "@storybook/types": "7.5.3", - "@types/semver": "^7.3.4", - "@yarnpkg/fslib": "2.10.3", - "@yarnpkg/libzip": "2.3.0", - "chalk": "^4.1.0", - "commander": "^6.2.1", - "cross-spawn": "^7.0.3", - "detect-indent": "^6.1.0", - "envinfo": "^7.7.3", - "execa": "^5.0.0", - "express": "^4.17.3", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "get-npm-tarball-url": "^2.0.3", - "get-port": "^5.1.1", - "giget": "^1.0.0", - "globby": "^11.0.2", - "jscodeshift": "^0.14.0", - "leven": "^3.1.0", - "ora": "^5.4.1", - "prettier": "^2.8.0", - "prompts": "^2.4.0", - "puppeteer-core": "^2.1.1", - "read-pkg-up": "^7.0.1", - "semver": "^7.3.7", - "simple-update-notifier": "^2.0.0", - "strip-json-comments": "^3.0.1", - "tempy": "^1.0.1", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "bin": { - "getstorybook": "bin/index.js", - "sb": "bin/index.js" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } + "license": "MIT" }, - "node_modules/@storybook/cli/node_modules/commander": { - "version": "6.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" } }, - "node_modules/@storybook/cli/node_modules/prettier": { - "version": "2.8.8", + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "dependencies": { + "@sinonjs/commons": "^3.0.0" } }, - "node_modules/@storybook/client-logger": { - "version": "7.5.3", + "node_modules/@storybook/addon-actions": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.3.4.tgz", + "integrity": "sha512-1y0yD3upKcyzNwwA6loAGW2cRDqExwl4oAT7GJQA4tmabI+fNwmANSgU/ezLvvSUf4Qo0eJHg2Zcn8y+Apq2eA==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/global": "^5.0.0" + "@storybook/global": "^5.0.0", + "@types/uuid": "^9.0.1", + "dequal": "^2.0.2", + "polished": "^4.2.2", + "uuid": "^9.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/codemod": { - "version": "7.5.3", + "node_modules/@storybook/addon-backgrounds": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.3.4.tgz", + "integrity": "sha512-o3nl7cN3x8erJNxLEv8YptanEQAnbqnaseOAsvSC6/nnSAcRYBSs3BvekKvo4CcpS2mxn7F5NJTBFYnCXzy8EA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.22.9", - "@babel/preset-env": "^7.22.9", - "@babel/types": "^7.22.5", - "@storybook/csf": "^0.1.0", - "@storybook/csf-tools": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@storybook/types": "7.5.3", - "@types/cross-spawn": "^6.0.2", - "cross-spawn": "^7.0.3", - "globby": "^11.0.2", - "jscodeshift": "^0.14.0", - "lodash": "^4.17.21", - "prettier": "^2.8.0", - "recast": "^0.23.1" + "@storybook/global": "^5.0.0", + "memoizerific": "^1.11.3", + "ts-dedent": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/codemod/node_modules/prettier": { - "version": "2.8.8", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/components": { - "version": "7.5.3", + "node_modules/@storybook/addon-controls": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.3.4.tgz", + "integrity": "sha512-qQcaK6dczsb6wXkzGZKOjUYNA7FfKBewRv6NvoVKYY6LfhllGOkmUAtYpdtQG8adsZWTSoZaAOJS2vP2uM67lw==", "dev": true, - "license": "MIT", "dependencies": { - "@radix-ui/react-select": "^1.2.2", - "@radix-ui/react-toolbar": "^1.0.4", - "@storybook/client-logger": "7.5.3", - "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "memoizerific": "^1.11.3", - "use-resize-observer": "^9.1.0", - "util-deprecate": "^1.0.2" + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "ts-dedent": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "storybook": "^8.3.4" } }, - "node_modules/@storybook/core-client": { - "version": "7.5.3", + "node_modules/@storybook/addon-docs": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.3.4.tgz", + "integrity": "sha512-TWauhqF/gJgfwPuWeM6KM3LwC+ErCOM+K2z16w3vgao9s67sij8lnrdAoQ0hjA+kw2/KAdCakFS6FyciG81qog==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/preview-api": "7.5.3" + "@mdx-js/react": "^3.0.0", + "@storybook/blocks": "8.3.4", + "@storybook/csf-plugin": "8.3.4", + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "8.3.4", + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "fs-extra": "^11.1.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "rehype-external-links": "^3.0.0", + "rehype-slug": "^6.0.0", + "ts-dedent": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/core-common": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/core-events": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@storybook/types": "7.5.3", - "@types/find-cache-dir": "^3.2.1", - "@types/node": "^18.0.0", - "@types/node-fetch": "^2.6.4", - "@types/pretty-hrtime": "^1.0.0", - "chalk": "^4.1.0", - "esbuild": "^0.18.0", - "esbuild-register": "^3.5.0", - "file-system-cache": "2.3.0", - "find-cache-dir": "^3.0.0", - "find-up": "^5.0.0", - "fs-extra": "^11.1.0", - "glob": "^10.0.0", - "handlebars": "^4.7.7", - "lazy-universal-dotenv": "^4.0.0", - "node-fetch": "^2.0.0", - "picomatch": "^2.3.0", - "pkg-dir": "^5.0.0", - "pretty-hrtime": "^1.0.3", - "resolve-from": "^5.0.0", + "node_modules/@storybook/addon-essentials": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.3.4.tgz", + "integrity": "sha512-C3+3hpmSn/8zdx5sXEP0eE6zMzxgRosHVZYfe9nBcMiEDp6UKVUyHVetWxEULOEgN46ysjcpllZ0bUkRYxi2IQ==", + "dev": true, + "dependencies": { + "@storybook/addon-actions": "8.3.4", + "@storybook/addon-backgrounds": "8.3.4", + "@storybook/addon-controls": "8.3.4", + "@storybook/addon-docs": "8.3.4", + "@storybook/addon-highlight": "8.3.4", + "@storybook/addon-measure": "8.3.4", + "@storybook/addon-outline": "8.3.4", + "@storybook/addon-toolbars": "8.3.4", + "@storybook/addon-viewport": "8.3.4", "ts-dedent": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/core-common/node_modules/glob": { - "version": "10.3.10", + "node_modules/@storybook/addon-highlight": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.3.4.tgz", + "integrity": "sha512-rxZTeuZyZ7RnU+xmRhS01COFLbGnVEmlUNxBw8ArsrTEZKW5PbKpIxNLTj9F0zdH8H0MfryJGP+Aadcm0oHWlw==", "dev": true, - "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "@storybook/global": "^5.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/core-common/node_modules/minimatch": { - "version": "9.0.3", + "node_modules/@storybook/addon-interactions": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.3.4.tgz", + "integrity": "sha512-ORxqe35wUmF7EDHo45mdDHiju3Ryk2pZ1vO9PyvW6ZItNlHt/IxAr7T/TysGejZ/eTBg6tMZR3ExGky3lTg/CQ==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "@storybook/global": "^5.0.0", + "@storybook/instrumenter": "8.3.4", + "@storybook/test": "8.3.4", + "polished": "^4.2.2", + "ts-dedent": "^2.2.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@storybook/core-common/node_modules/minipass": { - "version": "7.0.4", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/core-common/node_modules/pkg-dir": { - "version": "5.0.0", + "node_modules/@storybook/addon-links": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-8.3.4.tgz", + "integrity": "sha512-R1DjARmxRIKJDGIG6uxmQ1yFNyoQbb+QIPUFjgWCak8+AdLJbC7W+Esvo9F5hQfh6czyy0piiM3qj5hpQJVh3A==", "dev": true, - "license": "MIT", "dependencies": { - "find-up": "^5.0.0" + "@storybook/csf": "^0.1.11", + "@storybook/global": "^5.0.0", + "ts-dedent": "^2.0.0" }, - "engines": { - "node": ">=10" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.3.4" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } } }, - "node_modules/@storybook/core-events": { - "version": "7.5.3", + "node_modules/@storybook/addon-measure": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.3.4.tgz", + "integrity": "sha512-IJ6WKEbqmG+r7sukFjo+bVmPB2Zry04sylGx/OGyOh7zIhhqAqpwOwMHP0uQrc3tLNnUM6qB/o83UyYX79ql+A==", "dev": true, - "license": "MIT", "dependencies": { - "ts-dedent": "^2.0.0" + "@storybook/global": "^5.0.0", + "tiny-invariant": "^1.3.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/core-server": { - "version": "7.5.3", + "node_modules/@storybook/addon-outline": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.3.4.tgz", + "integrity": "sha512-kRRJTTLKM8gMfeh/e83djN5XLlc0hFtr9zKWxuZxaXt9Hmr+9tH/PRFtVK/S4SgqnBDoXk49Wgv6raiwj5/e3A==", "dev": true, - "license": "MIT", "dependencies": { - "@aw-web-design/x-default-browser": "1.4.126", - "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "7.5.3", - "@storybook/channels": "7.5.3", - "@storybook/core-common": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/csf": "^0.1.0", - "@storybook/csf-tools": "7.5.3", - "@storybook/docs-mdx": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager": "7.5.3", - "@storybook/node-logger": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/telemetry": "7.5.3", - "@storybook/types": "7.5.3", - "@types/detect-port": "^1.3.0", - "@types/node": "^18.0.0", - "@types/pretty-hrtime": "^1.0.0", - "@types/semver": "^7.3.4", - "better-opn": "^3.0.2", - "chalk": "^4.1.0", - "cli-table3": "^0.6.1", - "compression": "^1.7.4", - "detect-port": "^1.3.0", - "express": "^4.17.3", - "fs-extra": "^11.1.0", - "globby": "^11.0.2", - "ip": "^2.0.0", - "lodash": "^4.17.21", - "open": "^8.4.0", - "pretty-hrtime": "^1.0.3", - "prompts": "^2.4.0", - "read-pkg-up": "^7.0.1", - "semver": "^7.3.7", - "telejson": "^7.2.0", - "tiny-invariant": "^1.3.1", - "ts-dedent": "^2.0.0", - "util": "^0.12.4", - "util-deprecate": "^1.0.2", - "watchpack": "^2.2.0", - "ws": "^8.2.3" + "ts-dedent": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/csf": { - "version": "0.1.1", + "node_modules/@storybook/addon-toolbars": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.3.4.tgz", + "integrity": "sha512-Km1YciVIxqluDbd1xmHjANNFyMonEOtnA6e4MrnBnC9XkPXSigeFlj0JvxyI/zjBsLBoFRmQiwq55W6l3hQ9sA==", "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^2.19.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/csf-plugin": { - "version": "7.5.3", + "node_modules/@storybook/addon-viewport": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.3.4.tgz", + "integrity": "sha512-fU4LdXSSqIOLbCEh2leq/tZUYlFliXZBWr/+igQHdUoU7HY8RIImXqVUaR9wlCaTb48WezAWT60vJtwNijyIiQ==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/csf-tools": "7.5.3", - "unplugin": "^1.3.1" + "memoizerific": "^1.11.3" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/csf-tools": { - "version": "7.5.3", + "node_modules/@storybook/blocks": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.3.4.tgz", + "integrity": "sha512-1g4aCrd5CcN+pVhF2ATu9ZRVvAIgBMb2yF9KkCuTpdvqKDuDNK3sGb0CxjS7jp3LOvyjJr9laTOQsz8v8MQc5A==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/generator": "^7.22.9", - "@babel/parser": "^7.22.7", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "@storybook/csf": "^0.1.0", - "@storybook/types": "7.5.3", - "fs-extra": "^11.1.0", - "recast": "^0.23.1", - "ts-dedent": "^2.0.0" + "@storybook/csf": "^0.1.11", + "@storybook/global": "^5.0.0", + "@storybook/icons": "^1.2.10", + "@types/lodash": "^4.14.167", + "color-convert": "^2.0.1", + "dequal": "^2.0.2", + "lodash": "^4.17.21", + "markdown-to-jsx": "^7.4.5", + "memoizerific": "^1.11.3", + "polished": "^4.2.2", + "react-colorful": "^5.1.2", + "telejson": "^7.2.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.3.4" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } } }, - "node_modules/@storybook/docs-mdx": { - "version": "0.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@storybook/docs-tools": { - "version": "7.5.3", + "node_modules/@storybook/builder-vite": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-8.3.4.tgz", + "integrity": "sha512-Sa6SZ7LeHpkrnuvua8P8MR8e8a+MPKbyMmr9TqCCy8Ud/t4AM4kHY3JpJGtrgeK9l43fBnBwfdZYoRl5J6oWeA==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/core-common": "7.5.3", - "@storybook/preview-api": "7.5.3", - "@storybook/types": "7.5.3", - "@types/doctrine": "^0.0.3", - "doctrine": "^3.0.0", - "lodash": "^4.17.21" + "@storybook/csf-plugin": "8.3.4", + "@types/find-cache-dir": "^3.2.1", + "browser-assert": "^1.2.1", + "es-module-lexer": "^1.5.0", + "express": "^4.19.2", + "find-cache-dir": "^3.0.0", + "fs-extra": "^11.1.0", + "magic-string": "^0.30.0", + "ts-dedent": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@preact/preset-vite": "*", + "storybook": "^8.3.4", + "typescript": ">= 4.3.x", + "vite": "^4.0.0 || ^5.0.0", + "vite-plugin-glimmerx": "*" + }, + "peerDependenciesMeta": { + "@preact/preset-vite": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vite-plugin-glimmerx": { + "optional": true + } } }, - "node_modules/@storybook/global": { - "version": "5.0.0", + "node_modules/@storybook/builder-vite/node_modules/magic-string": { + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, - "license": "MIT" + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } }, - "node_modules/@storybook/instrumenter": { - "version": "7.5.3", + "node_modules/@storybook/components": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.3.4.tgz", + "integrity": "sha512-iQzLJd87uGbFBbYNqlrN/ABrnx3dUrL0tjPCarzglzshZoPCNOsllJeJx5TJwB9kCxSZ8zB9TTOgr7NXl+oyVA==", "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/channels": "7.5.3", - "@storybook/client-logger": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.5.3" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/manager": { - "version": "7.5.3", + "node_modules/@storybook/core": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.3.4.tgz", + "integrity": "sha512-4PZB91JJpuKfcjeOR2LXj3ABaPLLSd2P/SfYOKNCygrDstsQa/yay3/yN5Z9yi1cIG84KRr6/sUW+0x8HsGLPg==", "dev": true, - "license": "MIT", + "dependencies": { + "@storybook/csf": "^0.1.11", + "@types/express": "^4.17.21", + "better-opn": "^3.0.2", + "browser-assert": "^1.2.1", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0", + "esbuild-register": "^3.5.0", + "express": "^4.19.2", + "jsdoc-type-pratt-parser": "^4.0.0", + "process": "^0.11.10", + "recast": "^0.23.5", + "semver": "^7.6.2", + "util": "^0.12.5", + "ws": "^8.2.3" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/manager-api": { - "version": "7.5.3", + "node_modules/@storybook/csf": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.11.tgz", + "integrity": "sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/channels": "7.5.3", - "@storybook/client-logger": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/csf": "^0.1.0", - "@storybook/global": "^5.0.0", - "@storybook/router": "7.5.3", - "@storybook/theming": "7.5.3", - "@storybook/types": "7.5.3", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "semver": "^7.3.7", - "store2": "^2.14.2", - "telejson": "^7.2.0", - "ts-dedent": "^2.0.0" + "type-fest": "^2.19.0" + } + }, + "node_modules/@storybook/csf-plugin": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.3.4.tgz", + "integrity": "sha512-ZMFWYxeTN4GxCn8dyIH4roECyLDy29yv/QKM+pHM3AC5Ny2HWI35SohWao4fGBAFxPQFbR5hPN8xa6ofHPSSTg==", + "dev": true, + "dependencies": { + "unplugin": "^1.3.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "storybook": "^8.3.4" } }, - "node_modules/@storybook/mdx2-csf": { - "version": "1.1.0", + "node_modules/@storybook/global": { + "version": "5.0.0", "dev": true, "license": "MIT" }, - "node_modules/@storybook/node-logger": { - "version": "7.5.3", + "node_modules/@storybook/icons": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-1.2.12.tgz", + "integrity": "sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q==", "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@storybook/postinstall": { - "version": "7.5.3", + "node_modules/@storybook/instrumenter": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.3.4.tgz", + "integrity": "sha512-jVhfNOPekOyJmta0BTkQl9Z6rgRbFHlc0eV4z1oSrzaawSlc9TFzAeDCtCP57vg3FuBX8ydDYAvyZ7s4xPpLyg==", "dev": true, - "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@vitest/utils": "^2.0.5", + "util": "^0.12.4" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, - "node_modules/@storybook/preview": { - "version": "7.5.3", + "node_modules/@storybook/manager-api": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.3.4.tgz", + "integrity": "sha512-tBx7MBfPUrKSlD666zmVjtIvoNArwCciZiW/UJ8IWmomrTJRfFBnVvPVM2gp1lkDIzRHYmz5x9BHbYaEDNcZWQ==", "dev": true, - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.3.4" } }, "node_modules/@storybook/preview-api": { - "version": "7.5.3", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.3.4.tgz", + "integrity": "sha512-/YKQ3QDVSHmtFXXCShf5w0XMlg8wkfTpdYxdGv1CKFV8DU24f3N7KWulAgeWWCWQwBzZClDa9kzxmroKlQqx3A==", "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/channels": "7.5.3", - "@storybook/client-logger": "7.5.3", - "@storybook/core-events": "7.5.3", - "@storybook/csf": "^0.1.0", - "@storybook/global": "^5.0.0", - "@storybook/types": "7.5.3", - "@types/qs": "^6.9.5", - "dequal": "^2.0.2", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "synchronous-promise": "^2.0.15", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/preview-api/node_modules/qs": { - "version": "6.11.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "storybook": "^8.3.4" } }, "node_modules/@storybook/react": { - "version": "7.5.3", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.3.4.tgz", + "integrity": "sha512-PA7iQL4/9X2/iLrv+AUPNtlhTHJWhDao9gQIT1Hef39FtFk+TU9lZGbv+g29R1H9V3cHP5162nG2aTu395kmbA==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/core-client": "7.5.3", - "@storybook/docs-tools": "7.5.3", + "@storybook/components": "^8.3.4", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.5.3", - "@storybook/react-dom-shim": "7.5.3", - "@storybook/types": "7.5.3", + "@storybook/manager-api": "^8.3.4", + "@storybook/preview-api": "^8.3.4", + "@storybook/react-dom-shim": "8.3.4", + "@storybook/theming": "^8.3.4", "@types/escodegen": "^0.0.6", "@types/estree": "^0.0.51", - "@types/node": "^18.0.0", + "@types/node": "^22.0.0", "acorn": "^7.4.1", "acorn-jsx": "^5.3.1", "acorn-walk": "^7.2.0", "escodegen": "^2.1.0", "html-tags": "^3.1.0", - "lodash": "^4.17.21", "prop-types": "^15.7.2", "react-element-to-jsx-string": "^15.0.0", + "semver": "^7.3.7", "ts-dedent": "^2.0.0", "type-fest": "~2.19", "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "typescript": "*" + "@storybook/test": "8.3.4", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.3.4", + "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { + "@storybook/test": { + "optional": true + }, "typescript": { "optional": true } } }, "node_modules/@storybook/react-dom-shim": { - "version": "7.5.3", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.3.4.tgz", + "integrity": "sha512-L4llDvjaAzqPx6h4ddZMh36wPr75PrI2S8bXy+flLqAeVRYnRt4WNKGuxqH0t0U6MwId9+vlCZ13JBfFuY7eQQ==", "dev": true, - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.3.4" } }, "node_modules/@storybook/react-vite": { - "version": "7.5.3", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-8.3.4.tgz", + "integrity": "sha512-0Xm8eTH+jQ7SV4moLkPN4G6U2IDrqXPXUqsZdXaccepIMcD4G75foQFm2LOrFJuY+IMySPspKeTqf8OLskPppw==", "dev": true, - "license": "MIT", "dependencies": { "@joshwooding/vite-plugin-react-docgen-typescript": "0.3.0", "@rollup/pluginutils": "^5.0.2", - "@storybook/builder-vite": "7.5.3", - "@storybook/react": "7.5.3", - "@vitejs/plugin-react": "^3.0.1", + "@storybook/builder-vite": "8.3.4", + "@storybook/react": "8.3.4", + "find-up": "^5.0.0", "magic-string": "^0.30.0", - "react-docgen": "^6.0.2" + "react-docgen": "^7.0.0", + "resolve": "^1.22.8", + "tsconfig-paths": "^4.2.0" }, "engines": { - "node": ">=16" + "node": ">=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", + "storybook": "^8.3.4", + "vite": "^4.0.0 || ^5.0.0" } }, "node_modules/@storybook/react-vite/node_modules/@rollup/pluginutils": { @@ -5017,35 +2811,6 @@ } } }, - "node_modules/@storybook/react-vite/node_modules/@vitejs/plugin-react": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.20.12", - "@babel/plugin-transform-react-jsx-self": "^7.18.6", - "@babel/plugin-transform-react-jsx-source": "^7.19.6", - "magic-string": "^0.27.0", - "react-refresh": "^0.14.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.1.0-beta.0" - } - }, - "node_modules/@storybook/react-vite/node_modules/@vitejs/plugin-react/node_modules/magic-string": { - "version": "0.27.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@storybook/react-vite/node_modules/magic-string": { "version": "0.30.5", "dev": true, @@ -5062,6 +2827,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@storybook/react/node_modules/@types/node": { + "version": "22.7.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", + "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", + "dev": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, "node_modules/@storybook/react/node_modules/acorn": { "version": "7.4.1", "dev": true, @@ -5081,57 +2855,96 @@ "node": ">=0.4.0" } }, - "node_modules/@storybook/router": { - "version": "7.5.3", + "node_modules/@storybook/react/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true + }, + "node_modules/@storybook/test": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.3.4.tgz", + "integrity": "sha512-HRiUenitln8QPHu6DEWUg9s9cEoiGN79lMykzXzw9shaUvdEIhWCsh82YKtmB3GJPj6qcc6dZL/Aio8srxyGAg==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/client-logger": "7.5.3", - "memoizerific": "^1.11.3", - "qs": "^6.10.0" + "@storybook/csf": "^0.1.11", + "@storybook/global": "^5.0.0", + "@storybook/instrumenter": "8.3.4", + "@testing-library/dom": "10.4.0", + "@testing-library/jest-dom": "6.5.0", + "@testing-library/user-event": "14.5.2", + "@vitest/expect": "2.0.5", + "@vitest/spy": "2.0.5", + "util": "^0.12.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + "storybook": "^8.3.4" } }, - "node_modules/@storybook/router/node_modules/qs": { - "version": "6.11.2", + "node_modules/@storybook/test/node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" }, "engines": { - "node": ">=0.6" + "node": ">=18" + } + }, + "node_modules/@storybook/test/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@storybook/telemetry": { - "version": "7.5.3", + "node_modules/@storybook/test/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/client-logger": "7.5.3", - "@storybook/core-common": "7.5.3", - "@storybook/csf-tools": "7.5.3", - "chalk": "^4.1.0", - "detect-package-manager": "^2.0.1", - "fetch-retry": "^5.0.2", - "fs-extra": "^11.1.0", - "read-pkg-up": "^7.0.1" + "dequal": "^2.0.3" + } + }, + "node_modules/@storybook/test/node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@storybook/test/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@storybook/testing-library": { "version": "0.2.2", "dev": true, @@ -5143,37 +2956,16 @@ } }, "node_modules/@storybook/theming": { - "version": "7.5.3", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.3.4.tgz", + "integrity": "sha512-D4XVsQgTtpHEHLhwkx59aGy1GBwOedVr/mNns7hFrH8FjEpxrrWCuZQASq1ZpCl8LXlh7uvmT5sM2rOdQbGuGg==", "dev": true, - "license": "MIT", - "dependencies": { - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.5.3", - "@storybook/global": "^5.0.0", - "memoizerific": "^1.11.3" - }, "funding": { "type": "opencollective", "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/types": { - "version": "7.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@storybook/channels": "7.5.3", - "@types/babel__core": "^7.0.0", - "@types/express": "^4.7.0", - "file-system-cache": "2.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" + "storybook": "^8.3.4" } }, "node_modules/@swc/core": { @@ -5233,6 +3025,14 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/@swc/helpers": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", + "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@swc/types": { "version": "0.1.5", "dev": true, @@ -5285,6 +3085,57 @@ "dev": true, "license": "MIT" }, + "node_modules/@testing-library/jest-dom": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz", + "integrity": "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==", + "dev": true, + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@testing-library/react": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.0.0.tgz", @@ -5304,9 +3155,10 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.5.1", + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12", "npm": ">=6" @@ -5369,8 +3221,9 @@ } }, "node_modules/@types/babel__core": { - "version": "7.20.3", - "license": "MIT", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -5433,14 +3286,14 @@ } }, "node_modules/@types/command-line-args": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.0.tgz", - "integrity": "sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", + "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==" }, "node_modules/@types/command-line-usage": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.2.tgz", - "integrity": "sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg==" + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz", + "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==" }, "node_modules/@types/compression": { "version": "1.7.4", @@ -5482,22 +3335,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/cross-spawn": { - "version": "6.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cross-spawn/node_modules/@types/node": { - "version": "20.8.10", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, "node_modules/@types/debug": { "version": "4.1.10", "license": "MIT", @@ -5505,25 +3342,11 @@ "@types/ms": "*" } }, - "node_modules/@types/detect-port": { - "version": "1.3.4", - "dev": true, - "license": "MIT" - }, "node_modules/@types/doctrine": { - "version": "0.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ejs": { - "version": "3.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/emscripten": { - "version": "1.39.9", - "dev": true, - "license": "MIT" + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true }, "node_modules/@types/escodegen": { "version": "0.0.6", @@ -5540,14 +3363,15 @@ } }, "node_modules/@types/estree": { - "version": "1.0.4", - "dev": true, - "license": "MIT" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, "node_modules/@types/express": { - "version": "4.17.20", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -5581,8 +3405,9 @@ }, "node_modules/@types/find-cache-dir": { "version": "3.2.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/find-cache-dir/-/find-cache-dir-3.2.1.tgz", + "integrity": "sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==", + "dev": true }, "node_modules/@types/glob": { "version": "7.2.0", @@ -5720,9 +3545,10 @@ "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.14.200", - "dev": true, - "license": "MIT" + "version": "4.17.9", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz", + "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==", + "dev": true }, "node_modules/@types/mdast": { "version": "3.0.14", @@ -5732,17 +3558,13 @@ } }, "node_modules/@types/mdx": { - "version": "2.0.9", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "3.0.3", - "dev": true, - "license": "MIT" + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true }, - "node_modules/@types/mime-types": { - "version": "2.1.3", + "node_modules/@types/mime": { + "version": "3.0.3", "dev": true, "license": "MIT" }, @@ -5768,33 +3590,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/node-fetch": { - "version": "2.6.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/@types/node-fetch/node_modules/@types/node": { - "version": "20.8.10", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/pad-left": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/pad-left/-/pad-left-2.1.1.tgz", - "integrity": "sha512-Xd22WCRBydkGSApl5Bw0PhAOHKSVjNL3E3AwzKaps96IMraPqy5BvZIsBVK6JLwdybUzjHnuWVwpDd0JjTfHXA==" - }, "node_modules/@types/papaparse": { "version": "5.3.10", "dev": true, @@ -5815,11 +3610,6 @@ "version": "4.0.1", "license": "MIT" }, - "node_modules/@types/pretty-hrtime": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/prop-types": { "version": "15.7.9", "license": "MIT" @@ -5916,9 +3706,10 @@ } }, "node_modules/@types/resolve": { - "version": "1.20.4", - "dev": true, - "license": "MIT" + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true }, "node_modules/@types/semver": { "version": "7.5.4", @@ -5985,6 +3776,12 @@ "version": "0.0.3", "license": "MIT" }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true + }, "node_modules/@types/yargs": { "version": "17.0.29", "dev": true, @@ -6184,69 +3981,111 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-react": { - "version": "4.1.1", - "license": "MIT", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.2.tgz", + "integrity": "sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==", "dependencies": { - "@babel/core": "^7.23.2", - "@babel/plugin-transform-react-jsx-self": "^7.22.5", - "@babel/plugin-transform-react-jsx-source": "^7.22.5", - "@types/babel__core": "^7.20.3", - "react-refresh": "^0.14.0" + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0" + "vite": "^4.2.0 || ^5.0.0" } }, - "node_modules/@yarnpkg/esbuild-plugin-pnp": { - "version": "3.0.0-rc.15", + "node_modules/@vitest/expect": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", + "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "tslib": "^2.4.0" + "@vitest/spy": "2.0.5", + "@vitest/utils": "2.0.5", + "chai": "^5.1.1", + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=14.15.0" + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/pretty-format": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz", + "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==", + "dev": true, + "dependencies": { + "tinyrainbow": "^1.2.0" }, - "peerDependencies": { - "esbuild": ">=0.10.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@yarnpkg/fslib": { - "version": "2.10.3", + "node_modules/@vitest/expect/node_modules/@vitest/utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz", + "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@yarnpkg/libzip": "^2.3.0", - "tslib": "^1.13.0" + "@vitest/pretty-format": "2.0.5", + "estree-walker": "^3.0.3", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@yarnpkg/fslib/node_modules/tslib": { - "version": "1.14.1", + "node_modules/@vitest/expect/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "license": "0BSD" + "dependencies": { + "@types/estree": "^1.0.0" + } }, - "node_modules/@yarnpkg/libzip": { - "version": "2.3.0", + "node_modules/@vitest/pretty-format": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.1.tgz", + "integrity": "sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@types/emscripten": "^1.39.6", - "tslib": "^1.13.0" + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=12 <14 || 14.2 - 14.9 || >14.10.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/@yarnpkg/libzip/node_modules/tslib": { - "version": "1.14.1", + "node_modules/@vitest/spy": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", + "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==", "dev": true, - "license": "0BSD" + "dependencies": { + "tinyspy": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.1.tgz", + "integrity": "sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==", + "dev": true, + "dependencies": { + "@vitest/pretty-format": "2.1.1", + "loupe": "^3.1.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } }, "node_modules/abab": { "version": "2.0.6", @@ -6270,8 +4109,9 @@ } }, "node_modules/acorn": { - "version": "8.11.2", - "license": "MIT", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "bin": { "acorn": "bin/acorn" }, @@ -6304,14 +4144,6 @@ "node": ">=0.4.0" } }, - "node_modules/address": { - "version": "1.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -6324,18 +4156,6 @@ "node": ">= 6.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "license": "MIT", @@ -6414,34 +4234,36 @@ } }, "node_modules/apache-arrow": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-13.0.0.tgz", - "integrity": "sha512-3gvCX0GDawWz6KFNC28p65U+zGh/LZ6ZNKWNu74N6CQlKzxeoWHpi4CgEQsgRSEMuyrIIXi1Ea2syja7dwcHvw==", - "dependencies": { - "@types/command-line-args": "5.2.0", - "@types/command-line-usage": "5.0.2", - "@types/node": "20.3.0", - "@types/pad-left": "2.1.1", - "command-line-args": "5.2.1", - "command-line-usage": "7.0.1", - "flatbuffers": "23.5.26", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-17.0.0.tgz", + "integrity": "sha512-X0p7auzdnGuhYMVKYINdQssS4EcKec9TCXyez/qtJt32DrIMGbzqiaMiQ0X6fQlQpw8Fl0Qygcv4dfRAr5Gu9Q==", + "dependencies": { + "@swc/helpers": "^0.5.11", + "@types/command-line-args": "^5.2.3", + "@types/command-line-usage": "^5.0.4", + "@types/node": "^20.13.0", + "command-line-args": "^5.2.1", + "command-line-usage": "^7.0.1", + "flatbuffers": "^24.3.25", "json-bignum": "^0.0.3", - "pad-left": "^2.1.0", - "tslib": "^2.5.3" + "tslib": "^2.6.2" }, "bin": { - "arrow2csv": "bin/arrow2csv.js" + "arrow2csv": "bin/arrow2csv.cjs" } }, "node_modules/apache-arrow/node_modules/@types/node": { - "version": "20.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz", - "integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==" + "version": "20.16.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", + "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", + "dependencies": { + "undici-types": "~6.19.2" + } }, - "node_modules/app-root-dir": { - "version": "1.0.2", - "dev": true, - "license": "MIT" + "node_modules/apache-arrow/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, "node_modules/arg": { "version": "4.1.3", @@ -6452,17 +4274,6 @@ "version": "2.0.1", "license": "Python-2.0" }, - "node_modules/aria-hidden": { - "version": "1.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/aria-query": { "version": "5.1.3", "dev": true, @@ -6503,22 +4314,20 @@ "node": ">=8" } }, - "node_modules/assert": { - "version": "2.1.0", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "is-nan": "^1.3.2", - "object-is": "^1.1.5", - "object.assign": "^4.1.4", - "util": "^0.12.5" + "engines": { + "node": ">=12" } }, "node_modules/ast-types": { "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.0.1" }, @@ -6526,16 +4335,6 @@ "node": ">=4" } }, - "node_modules/async": { - "version": "3.2.5", - "dev": true, - "license": "MIT" - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/asynckit": { "version": "0.4.0", "license": "MIT" @@ -6597,14 +4396,6 @@ "proxy-from-env": "^1.1.0" } }, - "node_modules/babel-core": { - "version": "7.0.0-bridge.0", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -6692,50 +4483,6 @@ "npm": ">=6" } }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.3", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3", - "core-js-compat": "^3.33.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.3" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -6807,8 +4554,9 @@ }, "node_modules/better-opn": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz", + "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==", "dev": true, - "license": "MIT", "dependencies": { "open": "^8.0.4" }, @@ -6816,14 +4564,6 @@ "node": ">=12.0.0" } }, - "node_modules/big-integer": { - "version": "1.6.51", - "dev": true, - "license": "Unlicense", - "engines": { - "node": ">=0.6" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "license": "MIT", @@ -6831,56 +4571,6 @@ "node": ">=8" } }, - "node_modules/bl": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bl/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/body-parser": { "version": "1.20.2", "license": "MIT", @@ -6914,17 +4604,6 @@ "version": "2.0.0", "license": "MIT" }, - "node_modules/bplist-parser": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "big-integer": "^1.6.44" - }, - "engines": { - "node": ">= 5.10.0" - } - }, "node_modules/brace-expansion": { "version": "2.0.1", "license": "MIT", @@ -6944,20 +4623,14 @@ }, "node_modules/browser-assert": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz", + "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==", "dev": true }, - "node_modules/browserify-zlib": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "pako": "~0.2.0" - } - }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "funding": [ { "type": "opencollective", @@ -6973,10 +4646,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -6985,55 +4658,24 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, - "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, "engines": { - "node": "*" + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" } }, "node_modules/buffer-from": { @@ -7088,9 +4730,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001610", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz", - "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==", + "version": "1.0.30001666", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001666.tgz", + "integrity": "sha512-gD14ICmoV5ZZM1OdzPWmpx+q4GyefaK06zi8hmfHV5xe4/2nOQX3+Dw5o+fSqOws2xVwL9j+anOPFwHzdEdV4g==", "funding": [ { "type": "opencollective", @@ -7114,6 +4756,22 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/chai": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "dev": true, + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/chalk": { "version": "4.1.2", "license": "MIT", @@ -7184,6 +4842,15 @@ "pnpm": ">=8" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "engines": { + "node": ">= 16" + } + }, "node_modules/chokidar": { "version": "3.5.3", "funding": [ @@ -7209,11 +4876,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/chownr": { - "version": "1.1.4", - "dev": true, - "license": "ISC" - }, "node_modules/ci-info": { "version": "3.9.0", "dev": true, @@ -7238,76 +4900,6 @@ "version": "2.3.2", "license": "MIT" }, - "node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-table3": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cli-table3/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-table3/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -7365,38 +4957,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/clone": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -7427,11 +4987,6 @@ "version": "1.1.4", "license": "MIT" }, - "node_modules/colorette": { - "version": "2.0.20", - "dev": true, - "license": "MIT" - }, "node_modules/combined-stream": { "version": "1.0.8", "license": "MIT", @@ -7501,8 +5056,9 @@ }, "node_modules/commondir": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true }, "node_modules/compressible": { "version": "2.0.18", @@ -7556,20 +5112,6 @@ "version": "0.0.1", "license": "MIT" }, - "node_modules/concat-stream": { - "version": "1.6.2", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "node_modules/content-disposition": { "version": "0.5.4", "license": "MIT", @@ -7621,23 +5163,6 @@ "version": "1.0.6", "license": "MIT" }, - "node_modules/core-js-compat": { - "version": "3.33.2", - "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.22.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, "node_modules/cors": { "version": "2.8.5", "dev": true, @@ -7702,13 +5227,11 @@ "node": ">= 8" } }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true }, "node_modules/cssesc": { "version": "3.0.0", @@ -7827,6 +5350,15 @@ } } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-equal": { "version": "2.2.2", "dev": true, @@ -7868,32 +5400,6 @@ "node": ">=0.10.0" } }, - "node_modules/default-browser-id": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bplist-parser": "^0.2.0", - "untildify": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/define-data-property": { "version": "1.1.1", "license": "MIT", @@ -7908,8 +5414,9 @@ }, "node_modules/define-lazy-prop": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -7930,32 +5437,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/defu": { - "version": "6.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/del": { - "version": "6.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "license": "MIT", @@ -7985,14 +5466,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-indent": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -8002,35 +5475,6 @@ "node": ">=8" } }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/detect-package-manager": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "execa": "^5.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/detect-port": { - "version": "1.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -8116,25 +5560,6 @@ "node": ">=12" } }, - "node_modules/dotenv": { - "version": "16.3.1", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" - } - }, - "node_modules/dotenv-expand": { - "version": "10.0.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, "node_modules/downshift": { "version": "7.6.2", "license": "MIT", @@ -8153,44 +5578,18 @@ "version": "17.0.2", "license": "MIT" }, - "node_modules/duplexify": { - "version": "3.7.1", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", - "license": "MIT" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.4.736", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz", - "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==" + "version": "1.5.31", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.31.tgz", + "integrity": "sha512-QcDoBbQeYt0+3CWcK/rEbuHvwpbT/8SV9T3OSgs6cX1FlcUAkgrkqbg9zLnDrMM/rLamzQwal4LYFCiWk861Tg==" }, "node_modules/emittery": { "version": "0.13.1", @@ -8215,14 +5614,6 @@ "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -8235,17 +5626,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/envinfo": { - "version": "7.11.0", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/error-ex": { "version": "1.3.2", "license": "MIT", @@ -8272,50 +5652,56 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true + }, "node_modules/esbuild": { - "version": "0.18.20", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, - "node_modules/esbuild-plugin-alias": { - "version": "0.2.1", - "dev": true, - "license": "MIT" + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } }, "node_modules/esbuild-register": { - "version": "3.5.0", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -8324,8 +5710,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "license": "MIT", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -8689,33 +6076,6 @@ "version": "3.0.2", "license": "MIT" }, - "node_modules/extract-zip": { - "version": "1.7.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - } - }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "license": "MIT" @@ -8757,19 +6117,6 @@ "bser": "2.1.1" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fetch-retry": { - "version": "5.0.6", - "dev": true, - "license": "MIT" - }, "node_modules/file-entry-cache": { "version": "6.0.1", "license": "MIT", @@ -8784,34 +6131,6 @@ "version": "2.0.5", "license": "MIT" }, - "node_modules/file-system-cache": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fs-extra": "11.1.1", - "ramda": "0.29.0" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.0.1", "license": "MIT", @@ -8851,8 +6170,9 @@ }, "node_modules/find-cache-dir": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, - "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -8865,28 +6185,6 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/find-cache-dir/node_modules/make-dir": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/find-replace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", @@ -8929,22 +6227,14 @@ } }, "node_modules/flatbuffers": { - "version": "23.5.26", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-23.5.26.tgz", - "integrity": "sha512-vE+SI9vrJDwi1oETtTIFldC/o9GsVKRM+s6EL0nQgxXlYV1Vc4Tk30hj4xGICftInKQKj1F3up2n8UbIVobISQ==" + "version": "24.3.25", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.3.25.tgz", + "integrity": "sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==" }, "node_modules/flatted": { "version": "3.2.9", "license": "ISC" }, - "node_modules/flow-parser": { - "version": "0.220.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -9034,15 +6324,11 @@ "node": ">= 0.6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/fs-extra": { - "version": "11.1.1", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -9052,24 +6338,15 @@ "node": ">=14.14" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", - "license": "MIT", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -9109,6 +6386,15 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.2", "license": "MIT", @@ -9122,22 +6408,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-nonce": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/get-npm-tarball-url": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.17" - } - }, "node_modules/get-package-type": { "version": "0.1.0", "dev": true, @@ -9146,17 +6416,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-port": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-stream": { "version": "6.0.1", "dev": true, @@ -9168,50 +6427,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/giget": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "colorette": "^2.0.20", - "defu": "^6.1.2", - "https-proxy-agent": "^7.0.2", - "mri": "^1.2.0", - "node-fetch-native": "^1.4.0", - "pathe": "^1.1.1", - "tar": "^6.2.0" - }, - "bin": { - "giget": "dist/cli.mjs" - } - }, - "node_modules/giget/node_modules/agent-base": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/giget/node_modules/https-proxy-agent": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/github-slugger": { - "version": "1.5.0", - "dev": true, - "license": "ISC" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "dev": true }, "node_modules/glob": { "version": "7.2.3", @@ -9259,11 +6479,6 @@ "glob": "^7.1.6" } }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/globals": { "version": "13.23.0", "license": "MIT", @@ -9325,42 +6540,6 @@ "version": "1.4.0", "license": "MIT" }, - "node_modules/gunzip-maybe": { - "version": "1.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "browserify-zlib": "^0.1.4", - "is-deflate": "^1.0.0", - "is-gzip": "^1.0.0", - "peek-stream": "^1.1.0", - "pumpify": "^1.3.3", - "through2": "^2.0.3" - }, - "bin": { - "gunzip-maybe": "bin.js" - } - }, - "node_modules/handlebars": { - "version": "4.7.8", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "dev": true, @@ -9406,28 +6585,94 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-heading-rank/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", "dev": true, - "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "@types/hast": "^3.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/hasown": { - "version": "2.0.0", - "license": "MIT", + "node_modules/hast-util-to-string/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" + "@types/unist": "*" } }, "node_modules/hast-util-whitespace": { @@ -9460,11 +6705,6 @@ "version": "16.13.1", "license": "MIT" }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "dev": true, - "license": "ISC" - }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -9588,25 +6828,6 @@ "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.2.4", "license": "MIT", @@ -9667,8 +6888,9 @@ }, "node_modules/indent-string": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -9702,20 +6924,6 @@ "node": ">= 0.4" } }, - "node_modules/invariant": { - "version": "2.2.4", - "dev": true, - "license": "MIT", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "dev": true - }, "node_modules/ipaddr.js": { "version": "1.9.1", "license": "MIT", @@ -9724,11 +6932,15 @@ } }, "node_modules/is-absolute-url": { - "version": "3.0.3", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-arguments": { @@ -9855,15 +7067,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-deflate": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/is-docker": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, - "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -9899,8 +7107,9 @@ }, "node_modules/is-generator-function": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -9921,22 +7130,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-gzip": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-map": { "version": "2.0.2", "dev": true, @@ -9945,21 +7138,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "license": "MIT", @@ -9981,14 +7159,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/is-path-inside": { "version": "3.0.3", "license": "MIT", @@ -10107,17 +7277,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-weakmap": { "version": "2.0.1", "dev": true, @@ -10140,8 +7299,9 @@ }, "node_modules/is-wsl": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, - "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -10158,14 +7318,6 @@ "version": "2.0.0", "license": "ISC" }, - "node_modules/isobject": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.1", "dev": true, @@ -10274,23 +7426,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/jake": { - "version": "10.8.7", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -10916,61 +8051,13 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jscodeshift": { - "version": "0.14.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.13.16", - "@babel/parser": "^7.13.16", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-transform-modules-commonjs": "^7.13.8", - "@babel/preset-flow": "^7.13.13", - "@babel/preset-typescript": "^7.13.0", - "@babel/register": "^7.13.16", - "babel-core": "^7.0.0-bridge.0", - "chalk": "^4.1.2", - "flow-parser": "0.*", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.4", - "neo-async": "^2.5.0", - "node-dir": "^0.1.17", - "recast": "^0.21.0", - "temp": "^0.8.4", - "write-file-atomic": "^2.3.0" - }, - "bin": { - "jscodeshift": "bin/jscodeshift.js" - }, - "peerDependencies": { - "@babel/preset-env": "^7.1.6" - } - }, - "node_modules/jscodeshift/node_modules/ast-types": { - "version": "0.15.2", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/jscodeshift/node_modules/recast": { - "version": "0.21.5", + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", "dev": true, - "license": "MIT", - "dependencies": { - "ast-types": "0.15.2", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - }, "engines": { - "node": ">= 4" + "node": ">=12.0.0" } }, "node_modules/jsdom": { @@ -11064,8 +8151,9 @@ }, "node_modules/jsonfile": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -11088,14 +8176,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/kleur": { "version": "3.0.3", "dev": true, @@ -11104,19 +8184,6 @@ "node": ">=6" } }, - "node_modules/lazy-universal-dotenv": { - "version": "4.0.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "app-root-dir": "^1.0.2", - "dotenv": "^16.0.0", - "dotenv-expand": "^10.0.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/leven": { "version": "3.1.0", "dev": true, @@ -11163,8 +8230,9 @@ }, "node_modules/lodash": { "version": "4.17.21", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.assignwith": { "version": "4.2.0", @@ -11176,11 +8244,6 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.difference": { "version": "4.5.0", "license": "MIT" @@ -11195,21 +8258,6 @@ "version": "4.6.2", "license": "MIT" }, - "node_modules/log-symbols": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/longest-streak": { "version": "3.1.0", "license": "MIT", @@ -11228,14 +8276,13 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", + "node_modules/loupe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "get-func-name": "^2.0.1" } }, "node_modules/lz-string": { @@ -11258,23 +8305,27 @@ } }, "node_modules/make-dir": { - "version": "2.1.0", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "license": "MIT", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { - "version": "5.7.2", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/make-error": { @@ -11292,8 +8343,9 @@ }, "node_modules/map-or-similar": { "version": "1.5.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", + "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", + "dev": true }, "node_modules/markdown-table": { "version": "3.0.3", @@ -11304,62 +8356,15 @@ } }, "node_modules/markdown-to-jsx": { - "version": "7.3.2", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.5.0.tgz", + "integrity": "sha512-RrBNcMHiFPcz/iqIj0n3wclzHXjwS7mzjBNWecKKVhNTIxQepIix6Il/wZCn2Cg5Y1ow2Qi84+eJrryFRWBEWw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 10" }, - "peerDependencies": { - "react": ">= 0.14.0" - } - }, - "node_modules/mdast-util-definitions": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "unist-util-visit": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-is": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "peerDependencies": { + "react": ">= 0.14.0" } }, "node_modules/mdast-util-find-and-replace": { @@ -11575,8 +8580,9 @@ }, "node_modules/memoizerific": { "version": "1.11.3", + "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", + "integrity": "sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==", "dev": true, - "license": "MIT", "dependencies": { "map-or-similar": "^1.5.0" } @@ -12159,8 +9165,9 @@ }, "node_modules/min-indent": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -12185,51 +9192,13 @@ }, "node_modules/minimist": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "dev": true, - "license": "MIT" - }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -12294,74 +9263,15 @@ "node": ">= 0.6" } }, - "node_modules/neo-async": { - "version": "2.6.2", - "dev": true, - "license": "MIT" - }, - "node_modules/node-dir": { - "version": "0.1.17", - "dev": true, - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.2" - }, - "engines": { - "node": ">= 0.10.5" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch-native": { - "version": "1.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "dev": true, "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, "node_modules/nodemon": { "version": "3.0.1", @@ -12406,25 +9316,6 @@ "nopt": "bin/nopt.js" } }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "license": "MIT", @@ -12559,8 +9450,9 @@ }, "node_modules/open": { "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -12588,40 +9480,6 @@ "node": ">= 0.8.0" } }, - "node_modules/ora": { - "version": "5.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-limit": { "version": "3.1.0", "license": "MIT", @@ -12648,20 +9506,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-try": { "version": "2.2.0", "dev": true, @@ -12670,22 +9514,6 @@ "node": ">=6" } }, - "node_modules/pad-left": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-2.1.0.tgz", - "integrity": "sha512-HJxs9K9AztdIQIAIa/OIazRAUW/L6B9hbQDxO4X07roW3eo9XqZc2ur9bn1StH9CnbbI9EgvejHQX7CBpCF1QA==", - "dependencies": { - "repeat-string": "^1.5.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pako": { - "version": "0.2.9", - "dev": true, - "license": "MIT" - }, "node_modules/papaparse": { "version": "5.4.1", "dev": true, @@ -12802,29 +9630,19 @@ "node": ">=8" } }, - "node_modules/pathe": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, - "node_modules/peek-stream": { - "version": "1.1.3", + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "duplexify": "^3.5.0", - "through2": "^2.0.3" + "engines": { + "node": ">= 14.16" } }, - "node_modules/pend": { - "version": "1.2.0", - "dev": true, - "license": "MIT" - }, "node_modules/picocolors": { - "version": "1.0.0", - "license": "ISC" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -12836,14 +9654,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/pirates": { "version": "4.0.6", "license": "MIT", @@ -12922,9 +9732,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "funding": [ { "type": "opencollective", @@ -12941,8 +9751,8 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -13138,35 +9948,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-hrtime": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/process": { "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6.0" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/progress": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/prompts": { "version": "2.4.2", "dev": true, @@ -13221,114 +10011,15 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/puppeteer-core": { - "version": "2.1.1", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/mime-types": "^2.1.0", - "debug": "^4.1.0", - "extract-zip": "^1.6.6", - "https-proxy-agent": "^4.0.0", - "mime": "^2.0.3", - "mime-types": "^2.1.25", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^2.6.1", - "ws": "^6.1.0" - }, - "engines": { - "node": ">=8.16.0" - } - }, - "node_modules/puppeteer-core/node_modules/agent-base": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/puppeteer-core/node_modules/https-proxy-agent": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "5", - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/puppeteer-core/node_modules/mime": { - "version": "2.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/puppeteer-core/node_modules/rimraf": { - "version": "2.7.1", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/puppeteer-core/node_modules/ws": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", - "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0" + "node_modules/pstree.remy": { + "version": "1.1.8", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=6" } }, "node_modules/pure-rand": { @@ -13384,15 +10075,6 @@ ], "license": "MIT" }, - "node_modules/ramda": { - "version": "0.29.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ramda" - } - }, "node_modules/range-parser": { "version": "1.2.1", "license": "MIT", @@ -13500,8 +10182,9 @@ }, "node_modules/react-colorful": { "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", + "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", "dev": true, - "license": "MIT", "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" @@ -13597,23 +10280,24 @@ } }, "node_modules/react-docgen": { - "version": "6.0.4", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-7.0.3.tgz", + "integrity": "sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.18.9", "@babel/traverse": "^7.18.9", "@babel/types": "^7.18.9", "@types/babel__core": "^7.18.0", "@types/babel__traverse": "^7.18.0", - "@types/doctrine": "^0.0.6", + "@types/doctrine": "^0.0.9", "@types/resolve": "^1.20.2", "doctrine": "^3.0.0", "resolve": "^1.22.1", "strip-indent": "^4.0.0" }, "engines": { - "node": ">=14.18.0" + "node": ">=16.14.0" } }, "node_modules/react-docgen-typescript": { @@ -13624,11 +10308,6 @@ "typescript": ">= 4.3.x" } }, - "node_modules/react-docgen/node_modules/@types/doctrine": { - "version": "0.0.6", - "dev": true, - "license": "MIT" - }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -13738,14 +10417,6 @@ } } }, - "node_modules/react-inspector": { - "version": "6.0.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-is": { "version": "18.2.0", "license": "MIT" @@ -13869,57 +10540,13 @@ } }, "node_modules/react-refresh": { - "version": "0.14.0", - "license": "MIT", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "engines": { "node": ">=0.10.0" } }, - "node_modules/react-remove-scroll": { - "version": "2.5.5", - "dev": true, - "license": "MIT", - "dependencies": { - "react-remove-scroll-bar": "^2.3.3", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-remove-scroll-bar": { - "version": "2.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "react-style-singleton": "^2.2.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/react-resizable-panels": { "version": "0.0.55", "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-0.0.55.tgz", @@ -13959,28 +10586,6 @@ "react-dom": ">=16.8" } }, - "node_modules/react-style-singleton": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "get-nonce": "^1.0.0", - "invariant": "^2.2.4", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/react-window": { "version": "1.8.10", "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", @@ -14013,144 +10618,57 @@ "node": ">=0.10.0" } }, - "node_modules/read-pkg": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "dev": true, + "node_modules/readdirp": { + "version": "3.6.0", "license": "MIT", "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "picomatch": "^2.2.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8.10.0" } }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", + "node_modules/recast": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz", + "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==", "dev": true, - "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">= 4" } }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, - "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", + "node_modules/redent/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "min-indent": "^1.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/readdirp": { - "version": "3.6.0", - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recast": { - "version": "0.23.4", - "dev": true, - "license": "MIT", - "dependencies": { - "assert": "^2.0.0", - "ast-types": "^0.16.1", - "esprima": "~4.0.0", - "source-map": "~0.6.1", - "tslib": "^2.0.1" - }, - "engines": { - "node": ">= 4" - } - }, "node_modules/redux": { "version": "4.2.1", "license": "MIT", @@ -14165,34 +10683,10 @@ "redux": "^3.1.0 || ^4.0.0" } }, - "node_modules/regenerate": { - "version": "1.4.2", - "dev": true, - "license": "MIT" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/regenerator-runtime": { "version": "0.14.0", "license": "MIT" }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "dev": true, @@ -14209,95 +10703,149 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpu-core": { - "version": "5.3.2", + "node_modules/rehype-external-links": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz", + "integrity": "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-is-element": "^3.0.0", + "is-absolute-url": "^4.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/regjsparser": { - "version": "0.9.1", + "node_modules/rehype-external-links/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/rehype-external-links/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "node_modules/rehype-external-links/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "@types/unist": "^3.0.0" }, - "bin": { - "regjsparser": "bin/parser" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", + "node_modules/rehype-external-links/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-external-links": { - "version": "8.0.0", + "node_modules/rehype-external-links/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dev": true, - "license": "MIT", "dependencies": { - "extend": "^3.0.0", - "is-absolute-url": "^3.0.0", - "mdast-util-definitions": "^4.0.0", - "space-separated-tokens": "^1.0.0", - "unist-util-visit": "^2.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-external-links/node_modules/space-separated-tokens": { - "version": "1.1.5", + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", "dev": true, - "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-external-links/node_modules/unist-util-is": { - "version": "4.1.0", + "node_modules/rehype-slug/node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/rehype-slug/node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, + "node_modules/rehype-slug/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dev": true, - "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-external-links/node_modules/unist-util-visit": { - "version": "2.0.3", + "node_modules/rehype-slug/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dev": true, - "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-external-links/node_modules/unist-util-visit-parents": { - "version": "3.1.1", + "node_modules/rehype-slug/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dev": true, - "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", @@ -14354,73 +10902,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remark-slug": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "github-slugger": "^1.0.0", - "mdast-util-to-string": "^1.0.0", - "unist-util-visit": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-slug/node_modules/mdast-util-to-string": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-slug/node_modules/unist-util-is": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-slug/node_modules/unist-util-visit": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-slug/node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -14484,18 +10965,6 @@ "node": ">=10" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/reusify": { "version": "1.0.4", "license": "MIT", @@ -14518,16 +10987,36 @@ } }, "node_modules/rollup": { - "version": "3.29.4", - "license": "MIT", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "dependencies": { + "@types/estree": "1.0.6" + }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=14.18.0", + "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", "fsevents": "~2.3.2" } }, @@ -14591,11 +11080,9 @@ } }, "node_modules/semver": { - "version": "7.5.4", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -14679,17 +11166,6 @@ "version": "1.2.0", "license": "ISC" }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -14756,9 +11232,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -14780,34 +11256,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.16", - "dev": true, - "license": "CC0-1.0" - }, "node_modules/sprintf-js": { "version": "1.0.3", "dev": true, @@ -14852,21 +11300,18 @@ "node": ">= 0.4" } }, - "node_modules/store2": { - "version": "2.14.2", - "dev": true, - "license": "(MIT OR GPL-3.0)" - }, "node_modules/storybook": { - "version": "7.5.3", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.3.4.tgz", + "integrity": "sha512-nzvuK5TsEgJwcWGLGgafabBOxKn37lfJVv7ZoUVPgJIjk2mNRyJDFwYRJzUZaD37eiR/c/lQ6MoaeqlGwiXoxw==", "dev": true, - "license": "MIT", "dependencies": { - "@storybook/cli": "7.5.3" + "@storybook/core": "8.3.4" }, "bin": { - "sb": "index.js", - "storybook": "index.js" + "getstorybook": "bin/index.cjs", + "sb": "bin/index.cjs", + "storybook": "bin/index.cjs" }, "funding": { "type": "opencollective", @@ -14881,19 +11326,6 @@ "node": ">=10" } }, - "node_modules/stream-shift": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -15015,8 +11447,9 @@ }, "node_modules/strip-indent": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", + "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", "dev": true, - "license": "MIT", "dependencies": { "min-indent": "^1.0.1" }, @@ -15153,11 +11586,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/synchronous-promise": { - "version": "2.0.17", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/table-layout": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz", @@ -15246,204 +11674,36 @@ "sucrase": "^3.32.0" }, "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "node_modules/tailwindcss/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tar-stream/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/tar-stream/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/tar/node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/telejson": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "memoizerific": "^1.11.3" - } - }, - "node_modules/temp": { - "version": "0.8.4", - "dev": true, - "license": "MIT", - "dependencies": { - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/temp/node_modules/rimraf": { - "version": "2.6.3", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/tempy": { - "version": "1.0.1", - "dev": true, - "license": "MIT", + "node_modules/tailwindcss/node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dependencies": { - "del": "^6.0.0", - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.13.0" } }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", + "node_modules/telejson": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.2.0.tgz", + "integrity": "sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "memoizerific": "^1.11.3" } }, "node_modules/terser": { @@ -15499,19 +11759,29 @@ "node": ">=0.8" } }, - "node_modules/through2": { - "version": "2.0.5", + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/tiny-invariant": { - "version": "1.3.1", + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=14.0.0" + } }, "node_modules/tippy.js": { "version": "6.3.7", @@ -15542,11 +11812,6 @@ "node": ">=8.0" } }, - "node_modules/tocbot": { - "version": "4.21.6", - "dev": true, - "license": "MIT" - }, "node_modules/toidentifier": { "version": "1.0.1", "license": "MIT", @@ -15725,6 +11990,29 @@ } } }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/tslib": { "version": "2.6.2", "license": "0BSD" @@ -15770,11 +12058,6 @@ "node": ">= 0.6" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "dev": true, - "license": "MIT" - }, "node_modules/typesafe-actions": { "version": "5.1.0", "license": "MIT", @@ -15801,18 +12084,6 @@ "node": ">=8" } }, - "node_modules/uglify-js": { - "version": "3.17.4", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/undefsafe": { "version": "2.0.5", "license": "MIT" @@ -15822,42 +12093,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/unified": { "version": "10.1.2", "license": "MIT", @@ -15875,17 +12110,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unique-string": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/unist-builder": { "version": "3.0.1", "license": "MIT", @@ -15965,8 +12189,9 @@ }, "node_modules/universalify": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -15979,26 +12204,30 @@ } }, "node_modules/unplugin": { - "version": "1.5.0", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.14.1.tgz", + "integrity": "sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==", "dev": true, - "license": "MIT", "dependencies": { - "acorn": "^8.10.0", - "chokidar": "^3.5.3", - "webpack-sources": "^3.2.3", - "webpack-virtual-modules": "^0.5.0" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "dev": true, - "license": "MIT", + "acorn": "^8.12.1", + "webpack-virtual-modules": "^0.6.2" + }, "engines": { - "node": ">=8" + "node": ">=14.0.0" + }, + "peerDependencies": { + "webpack-sources": "^3" + }, + "peerDependenciesMeta": { + "webpack-sources": { + "optional": true + } } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -16013,10 +12242,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -16025,289 +12253,614 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "license": "BSD-2-Clause", + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uvu": { + "version": "0.5.6", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uvu/node_modules/diff": { + "version": "5.1.0", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/uvu/node_modules/kleur": { + "version": "4.1.5", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "devOptional": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", + "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "5.3.7", + "license": "MIT", "dependencies": { - "punycode": "^2.1.0" + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, + "node_modules/vfile-message": { + "version": "3.1.4", + "license": "MIT", "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/use-callback-ref": { - "version": "1.3.0", - "dev": true, - "license": "MIT", + "node_modules/vite": { + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", + "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", "dependencies": { - "tslib": "^2.0.0" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=10" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" }, "peerDependenciesMeta": { - "@types/react": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { "optional": true } } }, - "node_modules/use-resize-observer": { - "version": "9.1.0", + "node_modules/vite-plugin-eslint": { + "version": "1.8.1", "dev": true, "license": "MIT", "dependencies": { - "@juggle/resize-observer": "^3.3.1" + "@rollup/pluginutils": "^4.2.1", + "@types/eslint": "^8.4.5", + "rollup": "^2.77.2" }, "peerDependencies": { - "react": "16.8.0 - 18", - "react-dom": "16.8.0 - 18" + "eslint": ">=7", + "vite": ">=2" } }, - "node_modules/use-sidecar": { - "version": "1.1.2", + "node_modules/vite-plugin-eslint/node_modules/rollup": { + "version": "2.79.1", "dev": true, "license": "MIT", - "dependencies": { - "detect-node-es": "^1.1.0", - "tslib": "^2.0.0" + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "node": ">=10.0.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/use-sync-external-store": { - "version": "1.2.0", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" } }, - "node_modules/util": { - "version": "0.12.5", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "license": "MIT" + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/utils-merge": { - "version": "1.0.1", - "license": "MIT", + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">= 0.4.0" + "node": ">=12" } }, - "node_modules/uuid": { - "version": "9.0.1", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "node_modules/uvu": { - "version": "0.5.6", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "bin": { - "uvu": "bin.js" - }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/uvu/node_modules/diff": { - "version": "5.1.0", - "license": "BSD-3-Clause", + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.3.1" + "node": ">=12" } }, - "node_modules/uvu/node_modules/kleur": { - "version": "4.1.5", - "license": "MIT", + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "devOptional": true, - "license": "MIT" + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/v8-to-istanbul": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", - "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10.12.0" + "node": ">=12" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" } }, - "node_modules/vary": { - "version": "1.1.2", - "license": "MIT", + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 0.8" + "node": ">=12" } }, - "node_modules/vfile": { - "version": "5.3.7", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" } }, - "node_modules/vfile-message": { - "version": "3.1.4", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "node_modules/vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", - "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } + "node": ">=12" } }, - "node_modules/vite-plugin-eslint": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^4.2.1", - "@types/eslint": "^8.4.5", - "rollup": "^2.77.2" - }, - "peerDependencies": { - "eslint": ">=7", - "vite": ">=2" + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "node_modules/vite-plugin-eslint/node_modules/rollup": { - "version": "2.79.1", - "dev": true, - "license": "MIT", + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, "bin": { - "rollup": "dist/bin/rollup" + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=10.0.0" + "node": ">=12" }, "optionalDependencies": { - "fsevents": "~2.3.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/void-elements": { @@ -16344,26 +12897,6 @@ "loose-envify": "^1.0.0" } }, - "node_modules/watchpack": { - "version": "2.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -16373,18 +12906,11 @@ "node": ">=12" } }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/webpack-virtual-modules": { - "version": "0.5.0", - "dev": true, - "license": "MIT" + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true }, "node_modules/whatwg-encoding": { "version": "2.0.0", @@ -16492,11 +13018,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/wordwrapjs": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", @@ -16574,16 +13095,6 @@ "version": "1.0.2", "license": "ISC" }, - "node_modules/write-file-atomic": { - "version": "2.4.3", - "dev": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -16620,14 +13131,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/xtend": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -16638,8 +13141,9 @@ } }, "node_modules/yallist": { - "version": "4.0.0", - "license": "ISC" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { "version": "1.10.2", @@ -16701,15 +13205,6 @@ "node": ">=8" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yn": { "version": "3.1.1", "devOptional": true, diff --git a/frontend/package.json b/frontend/package.json index 7eeef43a04..f0a11d8f72 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -34,8 +34,8 @@ "@paralleldrive/cuid2": "^2.2.2", "@react-keycloak-fork/web": "^4.0.3", "@tippyjs/react": "^4.2.6", - "@vitejs/plugin-react": "^4.1.1", - "apache-arrow": "^13.0.0", + "@vitejs/plugin-react": "^4.3.2", + "apache-arrow": "^17.0.0", "autoprefixer": "^10.4.19", "axios": "^1.7.7", "chance": "^1.1.11", @@ -84,16 +84,16 @@ "resize-observer-polyfill": "^1.5.1", "tailwindcss": "^3.4.3", "typesafe-actions": "^5.1.0", - "vite": "^4.5.0" + "vite": "^5.4.8" }, "devDependencies": { "@babel/core": "^7.23.2", - "@storybook/addon-actions": "7.5.3", - "@storybook/addon-essentials": "7.5.3", - "@storybook/addon-interactions": "7.5.3", - "@storybook/addon-links": "7.5.3", - "@storybook/react": "7.5.3", - "@storybook/react-vite": "7.5.3", + "@storybook/addon-actions": "8.3.4", + "@storybook/addon-essentials": "8.3.4", + "@storybook/addon-interactions": "8.3.4", + "@storybook/addon-links": "8.3.4", + "@storybook/react": "8.3.4", + "@storybook/react-vite": "8.3.4", "@storybook/testing-library": "^0.2.2", "@swc/core": "^1.3.96", "@testing-library/react": "^14.0.0", @@ -128,7 +128,7 @@ "jest-environment-jsdom": "^29.7.0", "papaparse": "^5.4.1", "prettier": "^3.0.3", - "storybook": "7.5.3", + "storybook": "8.3.4", "tailwind-styled-components": "^2.2.0", "terser": "^5.24.0", "ts-jest": "^29.1.1", diff --git a/frontend/src/js/symbols/FormSymbol.stories.tsx b/frontend/src/js/symbols/FormSymbol.stories.tsx index cda6318768..517079bde8 100644 --- a/frontend/src/js/symbols/FormSymbol.stories.tsx +++ b/frontend/src/js/symbols/FormSymbol.stories.tsx @@ -1,16 +1,12 @@ -import { ComponentMeta, Story } from "@storybook/react"; -import { ComponentProps } from "react"; +import { Meta, StoryFn } from "@storybook/react"; import FormSymbol from "./FormSymbol"; -export default { +const meta = { title: "Symbols/FormSymbol", component: FormSymbol, -} as ComponentMeta; +} as Meta; -const Template: Story> = () => { - return ; -}; +export default meta; -export const Default = Template.bind({}); -Default.args = {}; +export const Default: StoryFn = () => ; diff --git a/frontend/src/js/symbols/QuerySymbol.stories.tsx b/frontend/src/js/symbols/QuerySymbol.stories.tsx index d3aa1e7ece..57286489aa 100644 --- a/frontend/src/js/symbols/QuerySymbol.stories.tsx +++ b/frontend/src/js/symbols/QuerySymbol.stories.tsx @@ -1,16 +1,11 @@ -import { ComponentMeta, Story } from "@storybook/react"; -import { ComponentProps } from "react"; +import { Meta, StoryFn } from "@storybook/react"; import QuerySymbol from "./QuerySymbol"; -export default { +const meta = { title: "Symbols/QuerySymbol", component: QuerySymbol, -} as ComponentMeta; +} as Meta; +export default meta; -const Template: Story> = () => { - return ; -}; - -export const Default = Template.bind({}); -Default.args = {}; +export const Default: StoryFn = () => ; diff --git a/frontend/src/js/ui-components/InputMultiSelect/InputMultiSelect.stories.tsx b/frontend/src/js/ui-components/InputMultiSelect/InputMultiSelect.stories.tsx index c46acdfafd..5332b312c6 100644 --- a/frontend/src/js/ui-components/InputMultiSelect/InputMultiSelect.stories.tsx +++ b/frontend/src/js/ui-components/InputMultiSelect/InputMultiSelect.stories.tsx @@ -1,4 +1,4 @@ -import { ComponentMeta, Story } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import { ComponentProps, useState } from "react"; import wordslist from "../../../fixtures/words.json"; @@ -15,11 +15,13 @@ export default { argTypes: { backgroundColor: { control: "#fafafa" }, }, -} as ComponentMeta; +} as Meta; -const Template: Story< - ComponentProps & { passOnResolve?: boolean } -> = ({ passOnResolve, ...args }) => { +type Props = ComponentProps & { + passOnResolve?: boolean; +}; + +const Render = ({ passOnResolve, ...args }: Props) => { const [loading, setLoading] = useState(false); const [options, setOptions] = useState( wl.map((w) => ({ label: w, value: w, disabled: Math.random() < 0.1 })), @@ -67,22 +69,26 @@ const Template: Story< ); }; -export const Default = Template.bind({}); -Default.args = { - indexPrefix: 5, - label: "This is a nice label", - tooltip: - "And here goes some tooltip that really helps the user understand what's going on", - disabled: false, - passOnResolve: true, - creatable: true, - loading: false, -}; -Default.argTypes = { - passOnResolve: { - type: { name: "boolean" }, +type Story = StoryObj; + +export const Default: Story = { + args: { + indexPrefix: 5, + label: "This is a nice label", + tooltip: + "And here goes some tooltip that really helps the user understand what's going on", + disabled: false, + passOnResolve: true, + creatable: true, + loading: false, }, - indexPrefix: { - type: { name: "number", required: false }, + argTypes: { + passOnResolve: { + type: { name: "boolean" }, + }, + indexPrefix: { + type: { name: "number", required: false }, + }, }, + render: Render, }; diff --git a/frontend/src/js/ui-components/InputPlain/InputPlain.stories.tsx b/frontend/src/js/ui-components/InputPlain/InputPlain.stories.tsx index 6214be05a4..0d8c73ce26 100644 --- a/frontend/src/js/ui-components/InputPlain/InputPlain.stories.tsx +++ b/frontend/src/js/ui-components/InputPlain/InputPlain.stories.tsx @@ -1,17 +1,21 @@ -import { ComponentMeta, Story } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import { ComponentProps, useState } from "react"; import InputPlain from "./InputPlain"; -export default { +const meta = { title: "FormComponents/InputPlain", component: InputPlain, argTypes: { backgroundColor: { control: "#fafafa" }, }, -} as ComponentMeta; +} as Meta; -const TemplateString: Story> = (args) => { +export default meta; + +type Story = StoryObj; + +const RenderWithString = (args: ComponentProps) => { const [value, setValue] = useState(""); console.log(value); @@ -25,20 +29,22 @@ const TemplateString: Story> = (args) => { ); }; -export const WithString = TemplateString.bind({}); -WithString.args = { - label: "This is a nice label", - tooltip: - "And here goes some tooltip that really helps the user understand what's going on", - indexPrefix: 5, -}; -WithString.argTypes = { - indexPrefix: { - type: { name: "number", required: false }, +export const WithString: Story = { + args: { + label: "This is a nice label", + tooltip: + "And here goes some tooltip that really helps the user understand what's going on", + indexPrefix: 5, + }, + argTypes: { + indexPrefix: { + type: { name: "number", required: false }, + }, }, + render: RenderWithString, }; -const TemplateNumber: Story> = (args) => { +const RenderWithNumber = (args: ComponentProps) => { const [value, setValue] = useState(null); console.log(value); @@ -53,15 +59,17 @@ const TemplateNumber: Story> = (args) => { ); }; -export const WithNumber = TemplateNumber.bind({}); -WithNumber.args = { - label: "This is a nice label", - tooltip: - "And here goes some tooltip that really helps the user understand what's going on", - indexPrefix: 5, -}; -WithNumber.argTypes = { - indexPrefix: { - type: { name: "number", required: false }, +export const WithNumber: Story = { + args: { + label: "This is a nice label", + tooltip: + "And here goes some tooltip that really helps the user understand what's going on", + indexPrefix: 5, + }, + argTypes: { + indexPrefix: { + type: { name: "number", required: false }, + }, }, + render: RenderWithNumber, }; diff --git a/frontend/src/js/ui-components/InputSelect/InputSelect.stories.tsx b/frontend/src/js/ui-components/InputSelect/InputSelect.stories.tsx index 1d9aa6969f..446bb3583e 100644 --- a/frontend/src/js/ui-components/InputSelect/InputSelect.stories.tsx +++ b/frontend/src/js/ui-components/InputSelect/InputSelect.stories.tsx @@ -1,4 +1,4 @@ -import { ComponentMeta, Story } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import { ComponentProps, useState } from "react"; import wordslist from "../../../fixtures/words.json"; @@ -14,9 +14,11 @@ export default { argTypes: { backgroundColor: { control: "#fafafa" }, }, -} as ComponentMeta; +} as Meta; -const Template: Story> = (args) => { +type Story = StoryObj; + +const RenderDefault = (args: ComponentProps) => { const [options] = useState( wl.map((w) => ({ label: w, value: w, disabled: Math.random() < 0.1 })), ); @@ -37,17 +39,19 @@ const Template: Story> = (args) => { ); }; -export const Default = Template.bind({}); -Default.args = { - label: "This is a nice label", - smallMenu: false, - tooltip: - "And here goes some tooltip that really helps the user understand what's going on", - disabled: false, - indexPrefix: 5, -}; -Default.argTypes = { - indexPrefix: { - type: { name: "number", required: false }, +export const Default: Story = { + args: { + label: "This is a nice label", + smallMenu: false, + tooltip: + "And here goes some tooltip that really helps the user understand what's going on", + disabled: false, + indexPrefix: 5, + }, + argTypes: { + indexPrefix: { + type: { name: "number", required: false }, + }, }, + render: RenderDefault, }; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 8d376b9839..a5937f003c 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "@emotion/react", - "moduleResolution": "node", + "moduleResolution": "bundler", "sourceMap": true, "inlineSourceMap": false, "inlineSources": false, @@ -34,7 +34,10 @@ }, "include": [ "src", - "node_modules/**/*/*.d.ts" + "node_modules/**/*/*.d.ts", + ".storybook/main.ts", + ".storybook/manager.js", + ".storybook/preview.tsx" ], "exclude": [ "node_modules", From 247355c39cb0ed998e86212f65cca0acee0164a1 Mon Sep 17 00:00:00 2001 From: Kai Rollmann Date: Wed, 2 Oct 2024 17:11:15 +0200 Subject: [PATCH 09/28] Fix define --- frontend/vite.config.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 5ba892a6fd..a32be845f6 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -27,8 +27,10 @@ export default defineConfig({ __BUILD_TIMESTAMP__: JSON.stringify( new Date().toISOString().split(".")[0].split("T").join(" "), ), - __BUILD_GIT_DESCRIBE__: fs.existsSync("./git_describe.txt") - ? fs.readFileSync("./git_describe.txt", "utf-8").trim() - : '"__BUILD_GIT_DESCRIBE__"', + __BUILD_GIT_DESCRIBE__: JSON.stringify( + fs.existsSync("./git_describe.txt") + ? fs.readFileSync("./git_describe.txt", "utf-8").trim() + : "__BUILD_GIT_DESCRIBE__", + ), }, }); From 720fb46303a4bd0d5436d213ea5e30874ec985d6 Mon Sep 17 00:00:00 2001 From: awildturtok <1553491+awildturtok@users.noreply.github.com> Date: Mon, 7 Oct 2024 15:39:49 +0200 Subject: [PATCH 10/28] =?UTF-8?q?test=20if=20query=20is=20initialized=20be?= =?UTF-8?q?fore=20building=20full-status=20that=20might=20c=E2=80=A6=20(#3?= =?UTF-8?q?586)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test if query is initialized before building full-status to avoid issues * Cleanup query overview in admin-ui * Shorten toString of MultiSelect FilterValue --- .../conquery/apiv1/QueryProcessor.java | 2 +- .../query/concept/filter/FilterValue.java | 36 +- .../models/execution/ManagedExecution.java | 3 +- .../resources/admin/rest/AdminResource.java | 22 +- .../resources/admin/ui/queries.html.ftl | 497 +++++++++--------- 5 files changed, 301 insertions(+), 259 deletions(-) diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java b/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java index d3f28b692e..069a2ddfe6 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/QueryProcessor.java @@ -129,7 +129,7 @@ public Stream getQueriesFiltered(DatasetId datasetId, UriBuilde ) .filter(q -> subject.isPermitted(q, Ability.READ)) .map(mq -> { - final OverviewExecutionStatus status = mq.buildStatusOverview(uriBuilder.clone(), subject); + final OverviewExecutionStatus status = mq.buildStatusOverview(subject); if (mq.isReadyToDownload()) { status.setResultUrls(getResultAssets(config.getResultProviders(), mq, uriBuilder, allProviders)); diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java index 6abb5725f5..ee9be78e84 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/query/concept/filter/FilterValue.java @@ -85,22 +85,45 @@ public Condition convertForTableExport(SqlIdColumns ids, ConversionContext conte @NoArgsConstructor @CPSType(id = FrontendFilterType.Fields.MULTI_SELECT, base = FilterValue.class) - @ToString(callSuper = true) public static class CQMultiSelectFilter extends FilterValue> { public CQMultiSelectFilter(@NsIdRef Filter> filter, Set value) { super(filter, value); } + @Override + public String toString() { + final String valueString; + if (getValue().size() > 20) { + valueString = getValue().size() + " values"; + } + else { + valueString = getValue().toString(); + } + + return "%s(value=%s)".formatted(FrontendFilterType.Fields.BIG_MULTI_SELECT, valueString); + } + } @NoArgsConstructor @CPSType(id = FrontendFilterType.Fields.BIG_MULTI_SELECT, base = FilterValue.class) - @ToString(callSuper = true) public static class CQBigMultiSelectFilter extends FilterValue> { public CQBigMultiSelectFilter(@NsIdRef Filter> filter, Set value) { super(filter, value); } + @Override + public String toString() { + final String valueString; + if (getValue().size() > 20) { + valueString = getValue().size() + " values"; + } + else { + valueString = getValue().toString(); + } + + return "%s(value=%s)".formatted(FrontendFilterType.Fields.BIG_MULTI_SELECT, valueString); + } } @NoArgsConstructor @@ -219,11 +242,10 @@ public GroupFilterValue deserialize(JsonParser p, DeserializationContext ctxt) t final Filter filter = nsIdDeserializer.deserialize(filterTraverse, ctxt); if (!(filter instanceof GroupFilter)) { - throw InvalidTypeIdException.from(filterNode.traverse(), GroupFilter.class, String.format("Expected filter of type %s but was: %s", GroupFilter.class, - filter != null - ? filter.getClass() - : null - )); + throw InvalidTypeIdException.from(filterNode.traverse(), + GroupFilter.class, + String.format("Expected filter of type %s but was: %s", GroupFilter.class, filter != null ? filter.getClass() : null) + ); } GroupFilter groupFilter = (GroupFilter) filter; diff --git a/backend/src/main/java/com/bakdata/conquery/models/execution/ManagedExecution.java b/backend/src/main/java/com/bakdata/conquery/models/execution/ManagedExecution.java index baeaca2288..55dafbee3b 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/execution/ManagedExecution.java +++ b/backend/src/main/java/com/bakdata/conquery/models/execution/ManagedExecution.java @@ -51,7 +51,6 @@ import com.fasterxml.jackson.annotation.OptBoolean; import com.google.common.base.Preconditions; import jakarta.validation.constraints.NotNull; -import jakarta.ws.rs.core.UriBuilder; import lombok.AccessLevel; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -289,7 +288,7 @@ public void start() { /** * Renders a lightweight status with meta information about this query. Computation an size should be small for this. */ - public OverviewExecutionStatus buildStatusOverview(UriBuilder url, Subject subject) { + public OverviewExecutionStatus buildStatusOverview(Subject subject) { OverviewExecutionStatus status = new OverviewExecutionStatus(); setStatusBase(subject, status); diff --git a/backend/src/main/java/com/bakdata/conquery/resources/admin/rest/AdminResource.java b/backend/src/main/java/com/bakdata/conquery/resources/admin/rest/AdminResource.java index 0f8039d7a3..ef315cf67e 100644 --- a/backend/src/main/java/com/bakdata/conquery/resources/admin/rest/AdminResource.java +++ b/backend/src/main/java/com/bakdata/conquery/resources/admin/rest/AdminResource.java @@ -9,6 +9,7 @@ import java.util.Optional; import java.util.OptionalLong; import java.util.UUID; +import java.util.stream.Stream; import jakarta.inject.Inject; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; @@ -21,6 +22,7 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilder; +import com.bakdata.conquery.apiv1.execution.ExecutionStatus; import com.bakdata.conquery.apiv1.execution.FullExecutionStatus; import com.bakdata.conquery.io.jersey.ExtraMimeTypes; import com.bakdata.conquery.io.storage.MetaStorage; @@ -78,9 +80,7 @@ public Response cancelJob(@PathParam(JOB_ID) UUID jobId) { info.send(new CancelJobMessage(jobId)); } - return Response - .seeOther(UriBuilder.fromPath("/admin/").path(AdminUIResource.class, "getJobs").build()) - .build(); + return Response.seeOther(UriBuilder.fromPath("/admin/").path(AdminUIResource.class, "getJobs").build()).build(); } @GET @@ -97,7 +97,7 @@ public boolean isBusy() { @GET @Path("/queries") - public FullExecutionStatus[] getQueries(@Auth Subject currentUser, @QueryParam("limit") OptionalLong maybeLimit, @QueryParam("since") Optional maybeSince) { + public Stream getQueries(@Auth Subject currentUser, @QueryParam("limit") OptionalLong maybeLimit, @QueryParam("since") Optional maybeSince) { final LocalDate since = maybeSince.map(LocalDate::parse).orElse(LocalDate.now()); final long limit = maybeLimit.orElse(100); @@ -105,13 +105,18 @@ public FullExecutionStatus[] getQueries(@Auth Subject currentUser, @QueryParam(" final MetaStorage storage = processor.getStorage(); - return storage.getAllExecutions().stream() + return storage.getAllExecutions() + .stream() .filter(t -> t.getCreationTime().toLocalDate().isAfter(since) || t.getCreationTime().toLocalDate().isEqual(since)) .limit(limit) .map(t -> { - Namespace namespace = processor.getDatasetRegistry().get(t.getDataset().getId()); try { - return t.buildStatusFull(currentUser, namespace); + if (t.isInitialized()) { + final Namespace namespace = processor.getDatasetRegistry().get(t.getDataset().getId()); + return t.buildStatusFull(currentUser, namespace); + } + + return t.buildStatusOverview(currentUser); } catch (ConqueryError e) { // Initialization of execution probably failed, so we construct a status based on the overview status @@ -121,8 +126,7 @@ public FullExecutionStatus[] getQueries(@Auth Subject currentUser, @QueryParam(" fullExecutionStatus.setError(e); return fullExecutionStatus; } - }) - .toArray(FullExecutionStatus[]::new); + }); } @POST diff --git a/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl b/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl index 032b5ed33a..165918873a 100644 --- a/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl +++ b/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl @@ -1,255 +1,272 @@ -<#import "templates/template.html.ftl" as layout> +<#import "templates/template.html.ftl" as layout /> <@layout.layout> - - -

Queries

- -
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- \ No newline at end of file + +

Queries

+ +
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ From 8988bf7c0f785f729476c7ec7c91d351da19c27c Mon Sep 17 00:00:00 2001 From: awildturtok <1553491+awildturtok@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:39:29 +0200 Subject: [PATCH 11/28] undo using ftl in JS context (#3592) --- .../resources/admin/ui/queries.html.ftl | 147 +++++++++--------- 1 file changed, 72 insertions(+), 75 deletions(-) diff --git a/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl b/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl index 165918873a..ec2d689ffe 100644 --- a/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl +++ b/backend/src/main/resources/com/bakdata/conquery/resources/admin/ui/queries.html.ftl @@ -128,81 +128,78 @@ reloader = 0; } <#noparse > - function getHtmltemplate(data, queryCounter) { - return `
-
-
-
-
- ${data.id}: ${data.label} - ${data.ownerName} -
-
-
-
- Creation: ${((new Date(data.createdAt)).toLocaleString(languageTag))} -
-
- Started: ${((new Date(data.startTime)).toLocaleString(languageTag))} -
-
- Finished: ${((new Date(data.finishTime)).toLocaleString(languageTag))} -
-
-
-
- Duration: ${data.requiredTime}ms -
-
- Type: ${data.queryType} -
-
- - -
-
-
style="display: none;"> -
-
-
bg-warning<# /if><#if data.status=="FAILED">bg-danger<# /if><#if data.status=="DONE">bg-success<# /if>" - role="progressbar" - style="width: <#if data.progress??>${data.progress * 100}%" - aria-valuenow="<#if data.progress??>${data.progress * 100}%" - aria-valuemin="0" aria - valuemax="100" > - <#if data.progress??> ${ data.progress * 100 }% -
-
-
-
-
-
-
-
-
<#if data.query??>${JSON.stringify(data.query, undefined, 2)}
-
-
-
-
-
-
-
<#if data.error??>${JSON.stringify(data.error, undefined, 2)}
-
-
-
-
-
-
-
-` - } - + function getHtmltemplate(data, queryCounter) { + return ` +
+
+
+
+
+ ${data.ownerName} - ${data.id}/${data.label} +
+
+
+
+ Created: ${((new Date(data.createdAt)).toLocaleString(languageTag))} +
+
+ Started: ${((new Date(data.startTime)).toLocaleString(languageTag))} +
+
+ Finished: ${((new Date(data.finishTime)).toLocaleString(languageTag))} +
+
+
+
+ Duration: ${data.requiredTime} ms +
+
+ Type : ${data.queryType} +
+
+ + +
+
+
+
+
+
+ ${(data.progress && data.progress != null ? data.progress*100 : 0 )} % +
+
+
+
+
+
+
+
+
  ${(data.query ? JSON.stringify(data.query, undefined, 2) : '')}  
+
+
+
+
+
+
+
  ${(data.error ? JSON.stringify(data.error, undefined, 2) : '')}  
+
+
+
+
+
+
+
+ ` + } +

Queries