From 5dcf38ba0adfc8db2825f2411641e6edb2925205 Mon Sep 17 00:00:00 2001 From: Stefan Feilmeier Date: Sun, 3 Mar 2024 16:12:39 +0100 Subject: [PATCH] FEMS Backports 2024.3.0 (#2560) - GoodWe Grid-Meter: add support for "Commercial Meter - Sum: improvements to max-ever-values - Calculate min/max ever ESS discharge power (will eventually replace MaxApparentPower in UI Live) - add EssMinDischargePower and EssMaxDischargePower channels to _sum - calculate _sum/EssDischargePower also from non-hybrid ESS - improve parsing of _sum config: parse String values to int - Prediction: fix possible NoSuchElementException if all predictions are empty - AppCenter: App for EZA-Regler - Implement generic LinuxFs GPIO (for Modberry) - CI: Update scripts - AppCenter: Home 20 & 30 added modbus for external meters - AppCenter: ToU only compatibility with Home 10, 20 or 30 _(this shows compatibility restrictions in AppCenter; for proprietary distributions of OpenEMS change this accordingly)_ - Implement system SOFT/HARD restart (Edge JsonRPC) - Add JSON-RPC handler for system restart (`ExecuteSystemRestart`) - HARD: reboot system - SOFT: restart OpenEMS service - Extract handling of system commands to common `SystemRecord` record - UI: change "Installateurszugang anlegen" to "Account anlegen" - UI: Refactoring of translations - AppCenter: fix AlpitronicEvcs wrong scheduler factory id - GoodWe 20 & 30: handle Voltage & Current for DSP version - UI: chartjs-migration - UI: Fix Time-of-use bugs - AppCenter: refactor pvInverter apps to use "new" props - Refactored PV-Inverter Apps to use "new" Props - Added selection of Phase to SolarEdge App - Changed description text of tibber token - RRD4j/Backend-Api: avoid exception during deactivate - Fix bug in ControllerApiBackend or TimedataRrd4jImpl which required a restart. - Fixes #2545 --------- Co-authored-by: Michael Grill <59126309+michaelgrill@users.noreply.github.com> Co-authored-by: Sebastian Asen <47855186+sebastianasen@users.noreply.github.com> Co-authored-by: Lorant Meszlenyi <16509320+hydroid7@users.noreply.github.com> Co-authored-by: Hueseyin Sahutoglu <34771592+huseyinsaht@users.noreply.github.com> Co-authored-by: Stefan Feilmeier <3515268+sfeilmeier@users.noreply.github.com> Co-authored-by: Kai Jeschek <99220919+da-Kai@users.noreply.github.com> Co-authored-by: Lukas Rieger <73471197+lukasrgr@users.noreply.github.com> Co-authored-by: Sagar Venu <32655208+venu-sagar@users.noreply.github.com> --- .../common/oem/DummyOpenemsEdgeOem.java | 1 + .../io/openems/common/utils/EnumUtils.java | 24 + .../io/openems/common/utils/JsonUtils.java | 14 +- io.openems.edge.application/EdgeApp.bndrun | 2 + .../api/backend/ControllerApiBackendImpl.java | 7 +- .../ResendHistoricDataWorkerFactory.java | 36 + .../backend/ControllerApiBackendImplTest.java | 2 +- .../DummyResendHistoricDataWorkerFactory.java | 38 + .../edge/app/api/ModbusTcpApiReadOnly.java | 1 + .../edge/app/api/ModbusTcpApiReadWrite.java | 17 +- .../edge/app/api/RestJsonApiReadWrite.java | 12 +- .../edge/app/common/props/ComponentProps.java | 6 +- .../edge/app/common/props/PropsUtil.java | 30 +- .../openems/edge/app/ess/FixActivePower.java | 12 +- .../edge/app/ess/PowerPlantController.java | 148 + .../edge/app/ess/PrepareBatteryExtension.java | 13 +- .../openems/edge/app/evcs/AlpitronicEvcs.java | 9 +- .../io/openems/edge/app/evcs/DezonyEvcs.java | 3 +- .../openems/edge/app/evcs/HardyBarthEvcs.java | 11 +- .../openems/edge/app/evcs/IesKeywattEvcs.java | 3 +- .../io/openems/edge/app/evcs/KebaEvcs.java | 3 +- .../edge/app/evcs/WebastoNextEvcs.java | 3 +- .../edge/app/evcs/WebastoUniteEvcs.java | 3 +- .../app/integratedsystem/FeneconHome.java | 23 +- .../app/integratedsystem/FeneconHome20.java | 40 +- .../app/integratedsystem/FeneconHome30.java | 40 +- .../FeneconHomeComponents.java | 46 +- .../GoodWeGridMeterCategory.java | 26 + .../IntegratedSystemProps.java | 47 + .../edge/app/meter/AbstractMeterApp.java | 45 - .../edge/app/meter/CarloGavazziMeter.java | 151 +- .../openems/edge/app/meter/JanitzaMeter.java | 2 +- .../io/openems/edge/app/meter/KdkMeter.java | 2 +- .../edge/app/meter/MicrocareSdm630Meter.java | 2 +- .../openems/edge/app/meter/SocomecMeter.java | 2 +- .../app/pvinverter/AbstractPvInverter.java | 86 - .../CommonPvInverterConfiguration.java | 96 - .../app/pvinverter/FroniusPvInverter.java | 125 +- .../edge/app/pvinverter/KacoPvInverter.java | 114 +- .../edge/app/pvinverter/KostalPvInverter.java | 127 +- .../edge/app/pvinverter/PvInverterProps.java | 64 + .../edge/app/pvinverter/SmaPvInverter.java | 49 +- .../app/pvinverter/SolarEdgePvInverter.java | 123 +- .../GridOptimizedCharge.java | 7 +- .../SelfConsumptionOptimization.java | 3 + .../app/timeofusetariff/AwattarHourly.java | 12 +- .../edge/app/timeofusetariff/EntsoE.java | 13 +- .../timeofusetariff/StromdaoCorrently.java | 13 +- .../edge/app/timeofusetariff/Tibber.java | 12 +- .../edge/core/appmanager/ComponentUtil.java | 9 + .../core/appmanager/ComponentUtilImpl.java | 97 +- .../core/appmanager/dependency/Tasks.java | 27 + .../SchedulerAggregateTaskImpl.java | 15 +- .../SchedulerByCentralOrderAggregateTask.java | 5 + ...edulerByCentralOrderAggregateTaskImpl.java | 542 + .../SchedulerByCentralOrderConfiguration.java | 20 + .../core/appmanager/translation_de.properties | 14 +- .../core/appmanager/translation_en.properties | 15 +- .../io/openems/edge/core/host/HostImpl.java | 22 +- .../edge/core/host/OperatingSystem.java | 20 +- .../host/OperatingSystemDebianSystemd.java | 93 +- .../core/host/OperatingSystemWindows.java | 10 +- .../edge/core/host/SystemUpdateHandler.java | 12 +- .../jsonrpc/ExecuteSystemCommandRequest.java | 112 +- .../jsonrpc/ExecuteSystemCommandResponse.java | 64 +- .../jsonrpc/ExecuteSystemRestartRequest.java | 78 + .../jsonrpc/ExecuteSystemRestartResponse.java | 41 + .../jsonrpc/GetSystemUpdateStateResponse.java | 14 +- .../src/io/openems/edge/core/sum/Config.java | 6 + .../edge/core/sum/ExtremeEverValues.java | 11 +- .../src/io/openems/edge/core/sum/SumImpl.java | 5 + .../edge/app/evcs/TestEvcsCluster.java | 4 + .../app/integratedsystem/TestFeneconHome.java | 23 + .../integratedsystem/TestFeneconHome20.java | 3 + .../integratedsystem/TestFeneconHome30.java | 11 +- .../TestFeneconHome30DefaultRelays.java | 4 + .../edge/app/timeofusetariff/TestTibber.java | 29 +- .../AppManagerImpSynchronizationTest.java | 2 +- .../core/appmanager/AppManagerImplTest.java | 12 +- .../core/appmanager/AppManagerTestBundle.java | 112 +- .../io/openems/edge/core/appmanager/Apps.java | 11 + .../appmanager/ComponentUtilImplTest.java | 2 +- .../appmanager/DummyAppManagerAppHelper.java | 20 +- .../DummyPseudoComponentManager.java | 50 +- .../core/appmanager/TestTranslations.java | 1 + .../SchedulerAggregateTaskImplTest.java | 61 +- ...erByCentralOrderAggregateTaskImplTest.java | 337 + .../SchedulerOrderDefinitionTest.java | 198 + .../StaticIpAggregateTaskImplTest.java | 2 +- .../aggregatetask/TestScheduler.java | 93 + .../jsonrpc/ExecuteSystemResponseTest.java | 34 + .../io/openems/edge/core/sum/MyConfig.java | 22 + .../openems/edge/goodwe/gridmeter/Config.java | 9 + .../goodwe/gridmeter/GoodWeGridMeter.java | 15 +- .../gridmeter/GoodWeGridMeterCategory.java | 5 + .../goodwe/gridmeter/GoodWeGridMeterImpl.java | 96 +- .../gridmeter/GoodWeGridMeterImplTest.java | 58 + .../edge/goodwe/gridmeter/MyConfig.java | 33 + io.openems.edge.io.gpio/.classpath | 12 + io.openems.edge.io.gpio/.gitignore | 2 + io.openems.edge.io.gpio/.project | 23 + .../org.eclipse.core.resources.prefs | 2 + io.openems.edge.io.gpio/bnd.bnd | 13 + io.openems.edge.io.gpio/readme.adoc | 12 + .../src/io/openems/edge/io/gpio/Config.java | 29 + .../src/io/openems/edge/io/gpio/IoGpio.java | 21 + .../io/openems/edge/io/gpio/IoGpioImpl.java | 125 + .../edge/io/gpio/api/AbstractGpioChannel.java | 49 + .../openems/edge/io/gpio/api/DigitalIn.java | 15 + .../openems/edge/io/gpio/api/DigitalOut.java | 15 + .../edge/io/gpio/api/ReadChannelId.java | 16 + .../edge/io/gpio/api/WriteChannelId.java | 16 + .../io/gpio/hardware/HardwarePlatform.java | 73 + .../edge/io/gpio/hardware/HardwareType.java | 24 + .../io/gpio/hardware/ModBerryX500CM4.java | 45 + .../gpio/hardware/ModberryX500M40804Max.java | 35 + .../io/gpio/hardware/ModberryX500M40804W.java | 31 + .../gpio/hardware/ModberryX500M40804Wb.java | 31 + .../edge/io/gpio/linuxfs/Direction.java | 6 + .../io/openems/edge/io/gpio/linuxfs/Gpio.java | 118 + .../edge/io/gpio/linuxfs/HardwareFactory.java | 30 + .../io/gpio/linuxfs/LinuxFsDigitalIn.java | 15 + .../io/gpio/linuxfs/LinuxFsDigitalOut.java | 26 + io.openems.edge.io.gpio/test/.gitignore | 0 .../openems/edge/io/gpio/ModberryCM4Test.java | 265 + .../io/openems/edge/io/gpio/MyConfig.java | 89 + io.openems.edge.timedata.rrd4j/.gitignore | 1 - .../timedata/rrd4j/RecordWorkerFactory.java | 36 + .../timedata/rrd4j/TimedataRrd4jImpl.java | 7 +- .../rrd4j/DummyRecordWorkerFactory.java | 52 + .../timedata/rrd4j/TimedataRrd4jImplTest.java | 5 +- tools/build-debian-package.sh | 13 +- tools/common.sh | 45 +- ui/package-lock.json | 11213 +++++++++++++--- ui/package.json | 9 +- .../chart/totalchart.component.ts | 1 + .../Ess/TimeOfUseTariff/chart/chart.ts | 87 +- .../Ess/TimeOfUseTariff/flat/flat.html | 2 +- .../Ess/TimeOfUseTariff/flat/flat.ts | 1 - .../edge/history/abstracthistorychart.html | 3 +- .../app/edge/history/abstracthistorychart.ts | 192 +- .../edge/history/chpsoc/chart.component.ts | 19 +- .../consumption/chart/chart.constants.spec.ts | 6 +- .../common/consumption/chart/chart.spec.ts | 8 +- .../common/energy/chart/channels.spec.ts | 175 +- .../energy/chart/chart.constants.spec.ts | 2 +- .../history/common/energy/chart/chart.spec.ts | 16 +- .../edge/history/common/energy/chart/chart.ts | 4 +- .../common/grid/chart/chart.constants.spec.ts | 5 +- .../history/common/grid/chart/chart.spec.ts | 10 +- .../delayedselltogrid/chart.component.ts | 15 +- .../fixdigitaloutput/singlechart.component.ts | 21 +- .../fixdigitaloutput/totalchart.component.ts | 19 +- .../app/edge/history/grid/chart.component.ts | 9 +- .../gridoptimizedcharge/chart.component.ts | 90 +- .../sellToGridLimitChart.component.ts | 14 +- .../history/heatingelement/chart.component.ts | 34 +- .../edge/history/heatpump/chart.component.ts | 32 +- .../peakshaving/asymmetric/chart.component.ts | 18 +- .../peakshaving/symmetric/chart.component.ts | 10 +- .../peakshaving/timeslot/chart.component.ts | 17 +- ui/src/app/edge/history/shared.ts | 126 +- .../singlethreshold/chart.component.ts | 122 +- .../history/storage/chargerchart.component.ts | 13 +- .../history/storage/esschart.component.ts | 32 +- .../history/storage/singlechart.component.ts | 66 +- .../history/storage/socchart.component.ts | 108 +- .../history/storage/totalchart.component.ts | 33 +- .../Ess/GridOptimizedCharge/modal/modal.html | 12 +- .../modal/predictionChart.ts | 81 +- .../Ess/TimeOfUseTariff/modal/modal.html | 2 - .../TimeOfUseTariff/modal/powerSocChart.ts | 88 +- .../TimeOfUseTariff/modal/statePriceChart.ts | 82 +- .../modal/evcs-chart/evcs.chart.ts | 10 +- ui/src/app/shared/edge/edgeconfig.spec.ts | 17 +- ui/src/app/shared/formly/input.html | 8 +- .../chart/abstracthistorychart.html | 3 +- .../chart/abstracthistorychart.ts | 657 +- .../shared/testing/common.ts | 163 +- .../shared/testing/tester.ts | 18 +- .../formatSecondsToDuration.pipe.ts | 22 +- ui/src/app/shared/service/utils.ts | 24 +- ui/src/app/shared/shared.module.ts | 6 +- ui/src/app/shared/test/utils.spec.ts | 5 +- .../shared/utils/color/color.utils.spec.ts | 17 + ui/src/app/shared/utils/color/color.utils.ts | 37 + ui/src/app/shared/utils/date/dateutils.ts | 4 + ui/src/assets/i18n/de.json | 62 +- ui/src/assets/i18n/en.json | 61 +- ui/src/environments/index.ts | 23 +- ui/src/themes/openems/environments/theme.ts | 22 +- ui/src/themes/openems/scss/variables.scss | 3 +- 192 files changed, 15347 insertions(+), 4056 deletions(-) create mode 100644 io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ResendHistoricDataWorkerFactory.java create mode 100644 io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/DummyResendHistoricDataWorkerFactory.java create mode 100644 io.openems.edge.core/src/io/openems/edge/app/ess/PowerPlantController.java create mode 100644 io.openems.edge.core/src/io/openems/edge/app/integratedsystem/GoodWeGridMeterCategory.java delete mode 100644 io.openems.edge.core/src/io/openems/edge/app/meter/AbstractMeterApp.java delete mode 100644 io.openems.edge.core/src/io/openems/edge/app/pvinverter/AbstractPvInverter.java delete mode 100644 io.openems.edge.core/src/io/openems/edge/app/pvinverter/CommonPvInverterConfiguration.java create mode 100644 io.openems.edge.core/src/io/openems/edge/app/pvinverter/PvInverterProps.java create mode 100644 io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTask.java create mode 100644 io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImpl.java create mode 100644 io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderConfiguration.java create mode 100644 io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartRequest.java create mode 100644 io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartResponse.java create mode 100644 io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImplTest.java create mode 100644 io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerOrderDefinitionTest.java create mode 100644 io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/TestScheduler.java create mode 100644 io.openems.edge.core/test/io/openems/edge/core/host/jsonrpc/ExecuteSystemResponseTest.java create mode 100644 io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterCategory.java create mode 100644 io.openems.edge.io.gpio/.classpath create mode 100644 io.openems.edge.io.gpio/.gitignore create mode 100644 io.openems.edge.io.gpio/.project create mode 100644 io.openems.edge.io.gpio/.settings/org.eclipse.core.resources.prefs create mode 100644 io.openems.edge.io.gpio/bnd.bnd create mode 100644 io.openems.edge.io.gpio/readme.adoc create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/Config.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpio.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpioImpl.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/AbstractGpioChannel.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalIn.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalOut.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/ReadChannelId.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/WriteChannelId.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwarePlatform.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwareType.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModBerryX500CM4.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Max.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804W.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Wb.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Direction.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Gpio.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/HardwareFactory.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalIn.java create mode 100644 io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalOut.java create mode 100644 io.openems.edge.io.gpio/test/.gitignore create mode 100644 io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/ModberryCM4Test.java create mode 100644 io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/MyConfig.java create mode 100644 io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/RecordWorkerFactory.java create mode 100644 io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/DummyRecordWorkerFactory.java create mode 100644 ui/src/app/shared/utils/color/color.utils.spec.ts create mode 100644 ui/src/app/shared/utils/color/color.utils.ts diff --git a/io.openems.common/src/io/openems/common/oem/DummyOpenemsEdgeOem.java b/io.openems.common/src/io/openems/common/oem/DummyOpenemsEdgeOem.java index 2e266d20234..dba025ba18f 100644 --- a/io.openems.common/src/io/openems/common/oem/DummyOpenemsEdgeOem.java +++ b/io.openems.common/src/io/openems/common/oem/DummyOpenemsEdgeOem.java @@ -97,6 +97,7 @@ public SystemUpdateParams getSystemUpdateParams() { .put("App.PeakShaving.PeakShaving", "") // .put("App.PeakShaving.PhaseAccuratePeakShaving", "") // .put("App.Ess.FixActivePower", "") // + .put("App.Ess.PowerPlantController", "") // .put("App.Ess.PrepareBatteryExtension", "") // .build(); diff --git a/io.openems.common/src/io/openems/common/utils/EnumUtils.java b/io.openems.common/src/io/openems/common/utils/EnumUtils.java index f7a95592202..63b1ee9a1f1 100644 --- a/io.openems.common/src/io/openems/common/utils/EnumUtils.java +++ b/io.openems.common/src/io/openems/common/utils/EnumUtils.java @@ -13,6 +13,30 @@ public class EnumUtils { + /** + * Gets the Enum instance from the given value. + * + *

+ * This is a null-safe wrapper around {@link Enum#valueOf(Class, String)}. + * + * @param the type + * @param enumType the class of the {@link Enum} + * @param name the name of the constant to return + * @return the enum constant of the specified enum class with the specified + * name; null if there is no matching Enum constant + */ + public static > ENUM toEnum(Class enumType, String name) { + if (name == null || name.isBlank()) { + return null; + } + try { + return Enum.valueOf(enumType, name.toUpperCase()); + } catch (IllegalArgumentException e) { + // handled below + } + return null; + } + /** * Converts the Enum {@link CaseFormat#UPPER_UNDERSCORE} name to * {@link CaseFormat#UPPER_CAMEL}-case. diff --git a/io.openems.common/src/io/openems/common/utils/JsonUtils.java b/io.openems.common/src/io/openems/common/utils/JsonUtils.java index ba879c28d2c..36370520fd7 100644 --- a/io.openems.common/src/io/openems/common/utils/JsonUtils.java +++ b/io.openems.common/src/io/openems/common/utils/JsonUtils.java @@ -1,5 +1,7 @@ package io.openems.common.utils; +import static io.openems.common.utils.EnumUtils.toEnum; + import java.net.Inet4Address; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -2073,18 +2075,6 @@ private static String toString(JsonPrimitive jPrimitive) { return null; } - private static > E toEnum(Class enumType, String name) { - if (name == null || name.isBlank()) { - return null; - } - try { - return Enum.valueOf(enumType, name.toUpperCase()); - } catch (IllegalArgumentException e) { - // handled below - } - return null; - } - // CHECKSTYLE:OFF private static UUID toUUID(String value) { // CHECKSTYLE:ON diff --git a/io.openems.edge.application/EdgeApp.bndrun b/io.openems.edge.application/EdgeApp.bndrun index 0db74c25365..c52e366d9ff 100644 --- a/io.openems.edge.application/EdgeApp.bndrun +++ b/io.openems.edge.application/EdgeApp.bndrun @@ -132,6 +132,7 @@ bnd.identity;id='io.openems.edge.fenecon.pro',\ bnd.identity;id='io.openems.edge.goodwe',\ bnd.identity;id='io.openems.edge.io.filipowski',\ + bnd.identity;id='io.openems.edge.io.gpio',\ bnd.identity;id='io.openems.edge.io.kmtronic',\ bnd.identity;id='io.openems.edge.io.offgridswitch',\ bnd.identity;id='io.openems.edge.io.revpi',\ @@ -299,6 +300,7 @@ io.openems.edge.goodwe;version=snapshot,\ io.openems.edge.io.api;version=snapshot,\ io.openems.edge.io.filipowski;version=snapshot,\ + io.openems.edge.io.gpio;version=snapshot,\ io.openems.edge.io.kmtronic;version=snapshot,\ io.openems.edge.io.offgridswitch;version=snapshot,\ io.openems.edge.io.revpi;version=snapshot,\ diff --git a/io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ControllerApiBackendImpl.java b/io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ControllerApiBackendImpl.java index f45021163a0..eefbc0b7be3 100644 --- a/io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ControllerApiBackendImpl.java +++ b/io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ControllerApiBackendImpl.java @@ -23,7 +23,6 @@ import org.osgi.service.component.annotations.ConfigurationPolicy; import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceScope; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; import org.osgi.service.event.propertytypes.EventTopics; @@ -78,7 +77,8 @@ public class ControllerApiBackendImpl extends AbstractOpenemsComponent @Reference private OpenemsEdgeOem oem; - @Reference(scope = ReferenceScope.PROTOTYPE_REQUIRED) + @Reference + private ResendHistoricDataWorkerFactory resendHistoricDataWorkerFactory; protected ResendHistoricDataWorker resendHistoricDataWorker; @Reference @@ -150,6 +150,7 @@ private void activate(ComponentContext context, Config config) { this.websocket = new WebsocketClient(this, name, uri, httpHeaders, proxy); this.websocket.start(); + this.resendHistoricDataWorker = this.resendHistoricDataWorkerFactory.get(); this.resendHistoricDataWorker.setConfig(new ResendHistoricDataWorker.Config(// this.getUnableToSendChannel().address(), // this.getLastSuccessFulResendChannel().address(), // @@ -164,6 +165,8 @@ private void activate(ComponentContext context, Config config) { @Deactivate protected void deactivate() { super.deactivate(); + this.resendHistoricDataWorkerFactory.unget(this.resendHistoricDataWorker); + this.resendHistoricDataWorker = null; this.sendChannelValuesWorker.deactivate(); if (this.websocket != null) { this.websocket.stop(); diff --git a/io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ResendHistoricDataWorkerFactory.java b/io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ResendHistoricDataWorkerFactory.java new file mode 100644 index 00000000000..50ed1d64aa2 --- /dev/null +++ b/io.openems.edge.controller.api.backend/src/io/openems/edge/controller/api/backend/ResendHistoricDataWorkerFactory.java @@ -0,0 +1,36 @@ +package io.openems.edge.controller.api.backend; + +import org.osgi.service.component.ComponentServiceObjects; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +@Component(service = ResendHistoricDataWorkerFactory.class) +public class ResendHistoricDataWorkerFactory { + + @Reference + private ComponentServiceObjects cso; + + /** + * Returns a new {@link ResendHistoricDataWorker} service object. + * + * @return the created {@link ResendHistoricDataWorker} object + * @see #unget(ResendHistoricDataWorker) + */ + public ResendHistoricDataWorker get() { + return this.cso.getService(); + } + + /** + * Releases the {@link ResendHistoricDataWorker} service object. + * + * @param service a {@link ResendHistoricDataWorker} provided by this factory + * @see #get() + */ + public void unget(ResendHistoricDataWorker service) { + if (service == null) { + return; + } + this.cso.ungetService(service); + } + +} diff --git a/io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/ControllerApiBackendImplTest.java b/io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/ControllerApiBackendImplTest.java index 5a552803ee6..d5d49a61b28 100644 --- a/io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/ControllerApiBackendImplTest.java +++ b/io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/ControllerApiBackendImplTest.java @@ -39,7 +39,7 @@ public void test() throws Exception { new ComponentTest(sut) // .addReference("componentManager", new DummyComponentManager(clock)) // .addReference("cycle", new DummyCycle(1000)) // - .addReference("resendHistoricDataWorker", new ResendHistoricDataWorker()) // + .addReference("resendHistoricDataWorkerFactory", new DummyResendHistoricDataWorkerFactory()) // .addReference("oem", new DummyOpenemsEdgeOem()) // .addComponent(new DummySum()) // .activate(MyConfig.create() // diff --git a/io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/DummyResendHistoricDataWorkerFactory.java b/io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/DummyResendHistoricDataWorkerFactory.java new file mode 100644 index 00000000000..91aff08460e --- /dev/null +++ b/io.openems.edge.controller.api.backend/test/io/openems/edge/controller/api/backend/DummyResendHistoricDataWorkerFactory.java @@ -0,0 +1,38 @@ +package io.openems.edge.controller.api.backend; + +import java.lang.reflect.InvocationTargetException; + +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.ComponentServiceObjects; + +import io.openems.common.utils.ReflectionUtils; + +public class DummyResendHistoricDataWorkerFactory extends ResendHistoricDataWorkerFactory { + + public DummyResendHistoricDataWorkerFactory() + throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + super(); + ReflectionUtils.setAttribute(ResendHistoricDataWorkerFactory.class, this, "cso", + new DummyResendHistoricDataWorkerCso()); + } + + private static class DummyResendHistoricDataWorkerCso implements ComponentServiceObjects { + + @Override + public ResendHistoricDataWorker getService() { + return new ResendHistoricDataWorker(); + } + + @Override + public void ungetService(ResendHistoricDataWorker service) { + // empty for tests + } + + @Override + public ServiceReference getServiceReference() { + // empty for tests + return null; + } + } + +} diff --git a/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadOnly.java b/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadOnly.java index ba8049131d0..4298f4ebf23 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadOnly.java +++ b/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadOnly.java @@ -145,6 +145,7 @@ protected ThrowingTriFunction, L new EdgeConfig.Component(controllerId, this.getName(l), "Controller.Api.ModbusTcp.ReadOnly", JsonUtils.buildJsonObject() // .add("component.ids", componentIds) // + .addProperty("port", 502) // .build())); return AppConfiguration.create() // diff --git a/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadWrite.java b/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadWrite.java index aaa1490f53a..4aca80fbfd8 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadWrite.java +++ b/io.openems.edge.core/src/io/openems/edge/app/api/ModbusTcpApiReadWrite.java @@ -38,6 +38,7 @@ import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.DependencyDeclaration; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; /** @@ -164,15 +165,9 @@ protected ThrowingTriFunction, L new EdgeConfig.Component(controllerId, this.getName(l), "Controller.Api.ModbusTcp.ReadWrite", JsonUtils.buildJsonObject() // .addProperty("apiTimeout", apiTimeout) // - .add("component.ids", controllerIds).build()) // - ); - - final var schedulerIds = Lists.newArrayList(// - "ctrlEmergencyCapacityReserve0", // - controllerId, // - "ctrlGridOptimizedCharge0", // - "ctrlEssSurplusFeedToGrid0", // - "ctrlBalancing0" // + .add("component.ids", controllerIds) // + .addProperty("port", 502) // + .build()) // ); final var dependencies = Lists.newArrayList(// @@ -193,7 +188,9 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(schedulerIds)) // + .addTask(Tasks.schedulerByCentralOrder(// + new SchedulerComponent(controllerId, "Controller.Api.ModbusTcp.ReadWrite", + this.getAppId()))) // .addDependencies(dependencies) // .build(); }; diff --git a/io.openems.edge.core/src/io/openems/edge/app/api/RestJsonApiReadWrite.java b/io.openems.edge.core/src/io/openems/edge/app/api/RestJsonApiReadWrite.java index 863760cbbe7..e9b30745a37 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/api/RestJsonApiReadWrite.java +++ b/io.openems.edge.core/src/io/openems/edge/app/api/RestJsonApiReadWrite.java @@ -35,6 +35,7 @@ import io.openems.edge.core.appmanager.TranslationUtil; import io.openems.edge.core.appmanager.dependency.DependencyDeclaration; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; /** @@ -128,14 +129,6 @@ protected ThrowingTriFunction pickModbusId(// .setTranslatedDescription("communication.modbusId.description"); final var oldDefaultValue = def.getDefaultValue(); def.setDefaultValue((app, property, l, parameter) -> { - if (PropsUtil.isHomeInstalled(app.getAppManagerUtil())) { + // TODO should be configured in oem bundle + if (PropsUtil.isHome10Installed(app.getAppManagerUtil())) { return new JsonPrimitive("modbus1"); } + if (PropsUtil.isHome20Or30Installed(app.getAppManagerUtil())) { + return new JsonPrimitive("modbus2"); + } return oldDefaultValue.get(app, property, l, parameter); }); diff --git a/io.openems.edge.core/src/io/openems/edge/app/common/props/PropsUtil.java b/io.openems.edge.core/src/io/openems/edge/app/common/props/PropsUtil.java index 73896d6ce11..547da4b3c0a 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/common/props/PropsUtil.java +++ b/io.openems.edge.core/src/io/openems/edge/app/common/props/PropsUtil.java @@ -1,6 +1,8 @@ package io.openems.edge.app.common.props; import io.openems.edge.app.integratedsystem.FeneconHome; +import io.openems.edge.app.integratedsystem.FeneconHome20; +import io.openems.edge.app.integratedsystem.FeneconHome30; import io.openems.edge.core.appmanager.AppManagerUtil; public final class PropsUtil { @@ -9,7 +11,8 @@ private PropsUtil() { } /** - * Checks if a {@link FeneconHome} is installed. + * Checks if a {@link FeneconHome}, {@link FeneconHome20} or + * {@link FeneconHome30} is installed. * * @param util the {@link AppManagerUtil} to get the installed instances * @return true if a {@link FeneconHome} is installed otherwise false @@ -22,4 +25,29 @@ public static boolean isHomeInstalled(AppManagerUtil util) { ).isEmpty(); } + /** + * Checks if a {@link FeneconHome} is installed. + * + * @param util the {@link AppManagerUtil} to get the installed instances + * @return true if a {@link FeneconHome} is installed otherwise false + */ + public static boolean isHome10Installed(AppManagerUtil util) { + return !util.getInstantiatedAppsOf(// + "App.FENECON.Home" // + ).isEmpty(); + } + + /** + * Checks if a {@link FeneconHome20} or {@link FeneconHome30} is installed. + * + * @param util the {@link AppManagerUtil} to get the installed instances + * @return true if a {@link FeneconHome} is installed otherwise false + */ + public static boolean isHome20Or30Installed(AppManagerUtil util) { + return !util.getInstantiatedAppsOf(// + "App.FENECON.Home.20", // + "App.FENECON.Home.30" // + ).isEmpty(); + } + } diff --git a/io.openems.edge.core/src/io/openems/edge/app/ess/FixActivePower.java b/io.openems.edge.core/src/io/openems/edge/app/ess/FixActivePower.java index 7c3171fc676..cc39a74ac07 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/ess/FixActivePower.java +++ b/io.openems.edge.core/src/io/openems/edge/app/ess/FixActivePower.java @@ -41,6 +41,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; /** * Describes a fix active power app. @@ -144,16 +145,11 @@ protected ThrowingTriFunction, L .build()) // ); - // TODO improve scheduler configuration - final var schedulerIds = Lists.newArrayList(// - ctrlFixActivePowerId, // - "ctrlPrepareBatteryExtension0", // - "ctrlEmergencyCapacityReserve0", // - "ctrlGridOptimizedCharge0" // - ); return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(schedulerIds)) // + .addTask(Tasks.schedulerByCentralOrder(// + new SchedulerComponent(ctrlFixActivePowerId, "Controller.Ess.FixActivePower", + this.getAppId()))) // .build(); }; } diff --git a/io.openems.edge.core/src/io/openems/edge/app/ess/PowerPlantController.java b/io.openems.edge.core/src/io/openems/edge/app/ess/PowerPlantController.java new file mode 100644 index 00000000000..74fa8228704 --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/app/ess/PowerPlantController.java @@ -0,0 +1,148 @@ +package io.openems.edge.app.ess; + +import static io.openems.edge.app.common.props.CommonProps.alias; + +import java.util.Map; +import java.util.function.Function; + +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +import com.google.common.collect.Lists; +import com.google.gson.JsonElement; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.function.ThrowingTriFunction; +import io.openems.common.oem.OpenemsEdgeOem; +import io.openems.common.session.Language; +import io.openems.common.session.Role; +import io.openems.common.types.EdgeConfig; +import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.ess.PowerPlantController.Property; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.core.appmanager.AbstractOpenemsApp; +import io.openems.edge.core.appmanager.AbstractOpenemsAppWithProps; +import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppDef; +import io.openems.edge.core.appmanager.AppDescriptor; +import io.openems.edge.core.appmanager.ComponentUtil; +import io.openems.edge.core.appmanager.ConfigurationTarget; +import io.openems.edge.core.appmanager.OpenemsApp; +import io.openems.edge.core.appmanager.OpenemsAppCardinality; +import io.openems.edge.core.appmanager.OpenemsAppCategory; +import io.openems.edge.core.appmanager.OpenemsAppPermissions; +import io.openems.edge.core.appmanager.Type; +import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; +import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; + +@Component(name = "App.Ess.PowerPlantController") +public class PowerPlantController extends AbstractOpenemsAppWithProps + implements OpenemsApp { + + public static enum Property implements Type { + // Component-IDs + CTRL_API_MODBUS_TCP_ID(AppDef.componentId("ctrlApiModbusTcp0")), // + // Properties + ALIAS(alias()), // + ; + + private final AppDef def; + + private Property(AppDef def) { + this.def = def; + } + + @Override + public Type self() { + return this; + } + + @Override + public AppDef def() { + return this.def; + } + + @Override + public Function, BundleParameter> getParamter() { + return Parameter.functionOf(AbstractOpenemsApp::getTranslationBundle); + } + + } + + @Activate + public PowerPlantController(// + @Reference ComponentManager componentManager, // + ComponentContext componentContext, // + @Reference ConfigurationAdmin cm, // + @Reference ComponentUtil componentUtil // + ) { + super(componentManager, componentContext, cm, componentUtil); + } + + @Override + public AppDescriptor getAppDescriptor(OpenemsEdgeOem oem) { + return AppDescriptor.create() // + .setWebsiteUrl(oem.getAppWebsiteUrl(this.getAppId())) // + .build(); + } + + @Override + public OpenemsAppCategory[] getCategories() { + return new OpenemsAppCategory[] { OpenemsAppCategory.ESS }; + } + + @Override + public OpenemsAppCardinality getCardinality() { + return OpenemsAppCardinality.SINGLE; + } + + @Override + protected PowerPlantController getApp() { + return this; + } + + @Override + protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { + return (t, p, l) -> { + final var ctrlApiModbusTcpId = this.getId(t, p, Property.CTRL_API_MODBUS_TCP_ID); + + final var alias = this.getString(p, l, Property.ALIAS); + + final var components = Lists.newArrayList(// + new EdgeConfig.Component(ctrlApiModbusTcpId, alias, "Controller.Api.ModbusTcp.ReadWrite", + JsonUtils.buildJsonObject() // + .addProperty("enabled", true) // + .addProperty("apiTimeout", 60) // + .addProperty("port", 510) // + .add("component.ids", JsonUtils.buildJsonArray() // + .add("_sum") // + .add("ess0") // + .build()) // + .build()) // + ); + + return AppConfiguration.create() // + .addTask(Tasks.component(components)) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlApiModbusTcpId, + "Controller.Api.ModbusTcp.ReadWrite", this.getAppId()))) // + .build(); + }; + } + + @Override + protected Property[] propertyValues() { + return Property.values(); + } + + @Override + public OpenemsAppPermissions getAppPermissions() { + return OpenemsAppPermissions.create() // + .setCanSee(Role.ADMIN) // + .build(); + } + +} diff --git a/io.openems.edge.core/src/io/openems/edge/app/ess/PrepareBatteryExtension.java b/io.openems.edge.core/src/io/openems/edge/app/ess/PrepareBatteryExtension.java index d6500c7d576..a3d0c7d6833 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/ess/PrepareBatteryExtension.java +++ b/io.openems.edge.core/src/io/openems/edge/app/ess/PrepareBatteryExtension.java @@ -39,6 +39,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; /** @@ -157,17 +158,11 @@ protected ThrowingTriFunction, L .build()) // ); - final var schedulerIds = Lists.newArrayList(// - ctrlPrepareBatteryExtensionId, // - "ctrlEmergencyCapacityReserve0", // - "ctrlGridOptimizedCharge0", // - "ctrlEssSurplusFeedToGrid0", // - "ctrlBalancing0" // - ); - return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(schedulerIds)) // + .addTask(Tasks.schedulerByCentralOrder(// + new SchedulerComponent(ctrlPrepareBatteryExtensionId, + "Controller.Ess.PrepareBatteryExtension", this.getAppId()))) // .build(); }; } diff --git a/io.openems.edge.core/src/io/openems/edge/app/evcs/AlpitronicEvcs.java b/io.openems.edge.core/src/io/openems/edge/app/evcs/AlpitronicEvcs.java index be5e8fe00cd..ad5cf6ed00d 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/evcs/AlpitronicEvcs.java +++ b/io.openems.edge.core/src/io/openems/edge/app/evcs/AlpitronicEvcs.java @@ -49,6 +49,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.Case; import io.openems.edge.core.appmanager.formly.DefaultValueOptions; import io.openems.edge.core.appmanager.formly.Exp; @@ -239,7 +240,7 @@ protected ThrowingTriFunction(); - final var schedulerIds = new ArrayList(); + final var schedulerIds = new ArrayList(); final var addedEvcsIds = new ArrayList(); final var ip = this.getString(p, l, Property.IP); @@ -253,7 +254,7 @@ protected ThrowingTriFunction b.addTask(Tasks.staticIp(new InterfaceConfiguration("eth0") // // range from 192.168.1.96 - 192.168.1.111 diff --git a/io.openems.edge.core/src/io/openems/edge/app/evcs/DezonyEvcs.java b/io.openems.edge.core/src/io/openems/edge/app/evcs/DezonyEvcs.java index b07c40861f7..acb60aef5e5 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/evcs/DezonyEvcs.java +++ b/io.openems.edge.core/src/io/openems/edge/app/evcs/DezonyEvcs.java @@ -42,6 +42,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; /** * Describes a dezony IQ evcs App. @@ -147,7 +148,7 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEvcsId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEvcsId, "Controller.Evcs", this.getAppId()))) // .addDependencies(EvcsCluster.dependency(t, this.componentManager, this.componentUtil, maxHardwarePowerPerPhase, evcsId)) // .build(); diff --git a/io.openems.edge.core/src/io/openems/edge/app/evcs/HardyBarthEvcs.java b/io.openems.edge.core/src/io/openems/edge/app/evcs/HardyBarthEvcs.java index 27c8bc8294b..ed993465b63 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/evcs/HardyBarthEvcs.java +++ b/io.openems.edge.core/src/io/openems/edge/app/evcs/HardyBarthEvcs.java @@ -52,6 +52,7 @@ import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.DependencyDeclaration; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.Case; import io.openems.edge.core.appmanager.formly.DefaultValueOptions; import io.openems.edge.core.appmanager.formly.Exp; @@ -311,13 +312,13 @@ OpenemsNamedException> appPropertyConfigurationFactory() { maxHardwarePowerPerPhase = OptionalInt.of(this.getInt(p, Property.MAX_HARDWARE_POWER)); } - final var schedulerIds = new ArrayList(); + final var schedulerIds = new ArrayList(); final var alias = this.getString(p, l, SubPropertyFirstChargepoint.ALIAS); final var ip = this.getString(p, l, SubPropertyFirstChargepoint.IP); final var evcsId = this.getId(t, p, Property.EVCS_ID); final var ctrlEvcsId = this.getId(t, p, Property.CTRL_EVCS_ID); - schedulerIds.add(ctrlEvcsId); + schedulerIds.add(new SchedulerComponent(ctrlEvcsId, "Controller.Evcs", this.getAppId())); final var factorieId = "Evcs.HardyBarth"; final var components = Lists.newArrayList(// @@ -334,7 +335,7 @@ OpenemsNamedException> appPropertyConfigurationFactory() { final var ipCp2 = this.getString(p, l, SubPropertySecondChargepoint.IP_CP_2); final var evcsIdCp2 = this.getId(t, p, Property.EVCS_ID_CP_2); final var ctrlEvcsIdCp2 = this.getId(t, p, Property.CTRL_EVCS_ID_CP_2); - schedulerIds.add(ctrlEvcsIdCp2); + schedulerIds.add(new SchedulerComponent(ctrlEvcsIdCp2, "Controller.Evcs", this.getAppId())); components.add(new EdgeConfig.Component(evcsIdCp2, aliasCp2, factorieId, JsonUtils.buildJsonObject() // .addProperty("ip", ipCp2) // @@ -354,11 +355,9 @@ OpenemsNamedException> appPropertyConfigurationFactory() { maxHardwarePowerPerPhase, removeIds, evcsId); } - schedulerIds.add("ctrlBalancing0"); - return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(schedulerIds)) // + .addTask(Tasks.schedulerByCentralOrder(schedulerIds)) // .throwingOnlyIf(ip.startsWith("192.168.25."), b -> b.addTask(Tasks.staticIp(new InterfaceConfiguration("eth0") // .addIp("Evcs", "192.168.25.10/24")))) // diff --git a/io.openems.edge.core/src/io/openems/edge/app/evcs/IesKeywattEvcs.java b/io.openems.edge.core/src/io/openems/edge/app/evcs/IesKeywattEvcs.java index 7b7b96936b3..9b339212730 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/evcs/IesKeywattEvcs.java +++ b/io.openems.edge.core/src/io/openems/edge/app/evcs/IesKeywattEvcs.java @@ -40,6 +40,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; /** @@ -153,7 +154,7 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEvcsId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEvcsId, "Controller.Evcs", this.getAppId()))) // .addDependencies(EvcsCluster.dependency(t, this.componentManager, this.componentUtil, maxHardwarePowerPerPhase, evcsId)) // .build(); diff --git a/io.openems.edge.core/src/io/openems/edge/app/evcs/KebaEvcs.java b/io.openems.edge.core/src/io/openems/edge/app/evcs/KebaEvcs.java index c78ec5e06c0..bf1344b7b9e 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/evcs/KebaEvcs.java +++ b/io.openems.edge.core/src/io/openems/edge/app/evcs/KebaEvcs.java @@ -41,6 +41,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; /** * Describes a Keba evcs App. @@ -140,7 +141,7 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEvcsId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEvcsId, "Controller.Evcs", this.getAppId()))) // .throwingOnlyIf(ip.startsWith("192.168.25."), b -> b.addTask(Tasks.staticIp(new InterfaceConfiguration("eth0") // .addIp("Evcs", "192.168.25.10/24")))) // diff --git a/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoNextEvcs.java b/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoNextEvcs.java index 9720fe5d198..32044ba31d6 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoNextEvcs.java +++ b/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoNextEvcs.java @@ -43,6 +43,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; /** * Describes a Webasto Next evcs App. @@ -160,7 +161,7 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEvcsId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEvcsId, "Controller.Evcs", this.getAppId()))) // .addDependencies(EvcsCluster.dependency(t, this.componentManager, this.componentUtil, maxHardwarePowerPerPhase, evcsId)) // .build(); diff --git a/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoUniteEvcs.java b/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoUniteEvcs.java index cb532e5da0f..8966672689a 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoUniteEvcs.java +++ b/io.openems.edge.core/src/io/openems/edge/app/evcs/WebastoUniteEvcs.java @@ -43,6 +43,7 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; /** * Describes a Webasto Unite evcs App. @@ -160,7 +161,7 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEvcsId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEvcsId, "Controller.Evcs", this.getAppId()))) // .addDependencies(EvcsCluster.dependency(t, this.componentManager, this.componentUtil, maxHardwarePowerPerPhase, evcsId)) // .build(); diff --git a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome.java b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome.java index e4cbe590520..a6013d13827 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome.java +++ b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome.java @@ -20,7 +20,6 @@ import static io.openems.edge.core.appmanager.ConfigurationTarget.VALIDATE; import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.ResourceBundle; @@ -65,6 +64,7 @@ import io.openems.edge.core.appmanager.Type; import io.openems.edge.core.appmanager.Type.Parameter.BundleProvider; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.Exp; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; @@ -410,17 +410,6 @@ AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { .build())); } - /* - * Set Execution Order for Scheduler. - */ - List schedulerExecutionOrder = new ArrayList<>(); - if (hasEmergencyReserve) { - schedulerExecutionOrder.add("ctrlEmergencyCapacityReserve0"); - } - schedulerExecutionOrder.add("ctrlGridOptimizedCharge0"); - schedulerExecutionOrder.add("ctrlEssSurplusFeedToGrid0"); - schedulerExecutionOrder.add("ctrlBalancing0"); - var dependencies = Lists.newArrayList(// gridOptimizedCharge(t, feedInType, maxFeedInPower), // selfConsumptionOptimization(t, essId, "meter0"), // @@ -431,9 +420,17 @@ AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { dependencies.add(acType.getDependency(modbusIdExternal)); } + final var schedulerComponents = new ArrayList(); + if (hasEmergencyReserve) { + schedulerComponents.add(new SchedulerComponent("ctrlEmergencyCapacityReserve0", + "Controller.Ess.EmergencyCapacityReserve", this.getAppId())); + } + schedulerComponents.add(new SchedulerComponent("ctrlEssSurplusFeedToGrid0", + "Controller.Ess.Hybrid.Surplus-Feed-To-Grid", this.getAppId())); + return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(schedulerExecutionOrder)) // + .addTask(Tasks.schedulerByCentralOrder(schedulerComponents)) // .addDependencies(dependencies) // .build(); }; diff --git a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome20.java b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome20.java index e8bb3ab9a41..23f9e6880ac 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome20.java +++ b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome20.java @@ -13,16 +13,19 @@ import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.gridOptimizedCharge; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.io; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.modbusExternal; +import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.modbusForExternalMeters; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.modbusInternal; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.power; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.predictor; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.prepareBatteryExtension; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.selfConsumptionOptimization; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.acMeterType; +import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.ctRatioFirst; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.emergencyReserveEnabled; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.emergencyReserveSoc; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.feedInSetting; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.feedInType; +import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.gridMeterType; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.hasAcMeter; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.hasEmergencyReserve; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.maxFeedInPower; @@ -31,7 +34,6 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.function.Function; @@ -73,6 +75,7 @@ import io.openems.edge.core.appmanager.Type; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.Exp; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; @@ -90,6 +93,8 @@ "FEED_IN_TYPE": {@link FeedInType}, "MAX_FEED_IN_POWER":5000, "FEED_IN_SETTING":"PU_ENABLE_CURVE", + "GRID_METER_CATEGORY":"SMART_METER", + "CT_RATIO_FIRST": 200, "HAS_AC_METER": false, "AC_METER_TYPE": {@link AcMeterType}, "HAS_PV_[1-4]":true, @@ -137,6 +142,9 @@ public enum Property implements PropertyParent { MAX_FEED_IN_POWER(maxFeedInPower(FEED_IN_TYPE)), // FEED_IN_SETTING(feedInSetting()), // + GRID_METER_CATEGORY(gridMeterType()), // + CT_RATIO_FIRST(ctRatioFirst(GRID_METER_CATEGORY)), // + HAS_AC_METER(hasAcMeter()), // AC_METER_TYPE(acMeterType(HAS_AC_METER)), // @@ -215,6 +223,7 @@ protected ThrowingTriFunction schedulerExecutionOrder = new ArrayList<>(); - if (hasEmergencyReserve) { - schedulerExecutionOrder.add("ctrlEmergencyCapacityReserve0"); - } - schedulerExecutionOrder.add("ctrlGridOptimizedCharge0"); - schedulerExecutionOrder.add("ctrlEssSurplusFeedToGrid0"); - schedulerExecutionOrder.add("ctrlBalancing0"); - final var dependencies = Lists.newArrayList(// gridOptimizedCharge(t, feedInType, maxFeedInPower), // selfConsumptionOptimization(t, essId, gridMeterId), // @@ -281,9 +291,17 @@ protected ThrowingTriFunction(); + if (hasEmergencyReserve) { + schedulerComponents.add(new SchedulerComponent("ctrlEmergencyCapacityReserve0", + "Controller.Ess.EmergencyCapacityReserve", this.getAppId())); + } + schedulerComponents.add(new SchedulerComponent("ctrlEssSurplusFeedToGrid0", + "Controller.Ess.Hybrid.Surplus-Feed-To-Grid", this.getAppId())); + return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(schedulerExecutionOrder)) // + .addTask(Tasks.schedulerByCentralOrder(schedulerComponents)) // .addDependencies(dependencies) // .build(); }; diff --git a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome30.java b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome30.java index 7fd9e15aed9..c71f223d38c 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome30.java +++ b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHome30.java @@ -13,16 +13,19 @@ import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.gridOptimizedCharge; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.io; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.modbusExternal; +import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.modbusForExternalMeters; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.modbusInternal; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.power; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.predictor; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.prepareBatteryExtension; import static io.openems.edge.app.integratedsystem.FeneconHomeComponents.selfConsumptionOptimization; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.acMeterType; +import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.ctRatioFirst; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.emergencyReserveEnabled; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.emergencyReserveSoc; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.feedInSetting; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.feedInType; +import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.gridMeterType; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.hasAcMeter; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.hasEmergencyReserve; import static io.openems.edge.app.integratedsystem.IntegratedSystemProps.maxFeedInPower; @@ -31,7 +34,6 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.function.Function; @@ -73,6 +75,7 @@ import io.openems.edge.core.appmanager.Type; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.Exp; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; @@ -90,6 +93,8 @@ "FEED_IN_TYPE": {@link FeedInType}, "MAX_FEED_IN_POWER":5000, "FEED_IN_SETTING":"PU_ENABLE_CURVE", + "GRID_METER_CATEGORY":"SMART_METER", + "CT_RATIO_FIRST": 200, "HAS_AC_METER": false, "AC_METER_TYPE": {@link AcMeterType}, "HAS_PV_[1-6]":true, @@ -137,6 +142,9 @@ public enum Property implements PropertyParent { MAX_FEED_IN_POWER(maxFeedInPower(FEED_IN_TYPE)), // FEED_IN_SETTING(feedInSetting()), // + GRID_METER_CATEGORY(gridMeterType()), // + CT_RATIO_FIRST(ctRatioFirst(GRID_METER_CATEGORY)), // + HAS_AC_METER(hasAcMeter()), // AC_METER_TYPE(acMeterType(HAS_AC_METER)), // @@ -215,6 +223,7 @@ protected ThrowingTriFunction schedulerExecutionOrder = new ArrayList<>(); - if (hasEmergencyReserve) { - schedulerExecutionOrder.add("ctrlEmergencyCapacityReserve0"); - } - schedulerExecutionOrder.add("ctrlGridOptimizedCharge0"); - schedulerExecutionOrder.add("ctrlEssSurplusFeedToGrid0"); - schedulerExecutionOrder.add("ctrlBalancing0"); - final var dependencies = Lists.newArrayList(// gridOptimizedCharge(t, feedInType, maxFeedInPower), // selfConsumptionOptimization(t, essId, gridMeterId), // @@ -282,9 +292,17 @@ protected ThrowingTriFunction(); + if (hasEmergencyReserve) { + schedulerComponents.add(new SchedulerComponent("ctrlEmergencyCapacityReserve0", + "Controller.Ess.EmergencyCapacityReserve", this.getAppId())); + } + schedulerComponents.add(new SchedulerComponent("ctrlEssSurplusFeedToGrid0", + "Controller.Ess.Hybrid.Surplus-Feed-To-Grid", this.getAppId())); + return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(schedulerExecutionOrder)) // + .addTask(Tasks.schedulerByCentralOrder(schedulerComponents)) // .addDependencies(dependencies) // .build(); }; diff --git a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHomeComponents.java b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHomeComponents.java index 5f96c323f0a..c5c89936f09 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHomeComponents.java +++ b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/FeneconHomeComponents.java @@ -133,15 +133,19 @@ public static EdgeConfig.Component io(// /** * Creates a default grid meter component for a FENECON Home. * - * @param bundle the translation bundle - * @param gridMeterId the id of the grid meter - * @param modbusIdExternal the id of the external modbus bridge + * @param bundle the translation bundle + * @param gridMeterId the id of the grid meter + * @param modbusIdExternal the id of the external modbus bridge + * @param gridMeterCategory the type of the Grid-Meter + * @param ctRatioFirst the first value of the CT-Ratio * @return the {@link Component} */ public static EdgeConfig.Component gridMeter(// final ResourceBundle bundle, // final String gridMeterId, // - final String modbusIdExternal // + final String modbusIdExternal, // + final GoodWeGridMeterCategory gridMeterCategory, // + final Integer ctRatioFirst // ) { return new EdgeConfig.Component(gridMeterId, // TranslationUtil.getTranslation(bundle, "gridMeterId.label"), "GoodWe.Grid-Meter", // @@ -149,6 +153,11 @@ public static EdgeConfig.Component gridMeter(// .addProperty("enabled", true) // .addProperty("modbus.id", modbusIdExternal) // .addProperty("modbusUnitId", 247) // + .addProperty("goodWeMeterCategory", gridMeterCategory) // + .onlyIf(gridMeterCategory == GoodWeGridMeterCategory.COMMERCIAL_METER, t -> { + t.addProperty("externalMeterRatioValueA", ctRatioFirst); + t.addProperty("externalMeterRatioValueB", 5 /* Default to 5 A */); + }) // .build()); } @@ -206,6 +215,35 @@ public static EdgeConfig.Component modbusExternal(// .build()); } + /** + * Creates a default external modbus component for external meters for a FENECON + * Home. + * + * @param bundle the translation bundle + * @param t the current {@link ConfigurationTarget} + * @param modbusIdExternal the id of the external modbus bridge + * @return the {@link Component} + */ + public static EdgeConfig.Component modbusForExternalMeters(// + final ResourceBundle bundle, // + final ConfigurationTarget t, // + final String modbusIdExternal // + ) { + return new EdgeConfig.Component(modbusIdExternal, + TranslationUtil.getTranslation(bundle, "App.IntegratedSystem.modbus2.alias"), "Bridge.Modbus.Serial", // + JsonUtils.buildJsonObject() // + .addProperty("enabled", true) // + .addProperty("baudRate", 9600) // + .addProperty("databits", 8) // + .addProperty("parity", Parity.NONE) // + .addProperty("portName", "/dev/bus0") // + .addProperty("stopbits", "ONE") // + .onlyIf(t == ConfigurationTarget.ADD, b -> { + b.addProperty("invalidateElementsAfterReadErrors", 1) // + .addProperty("logVerbosity", "NONE"); + }).build()); + } + /** * Creates a default predictor component for a FENECON Home. * diff --git a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/GoodWeGridMeterCategory.java b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/GoodWeGridMeterCategory.java new file mode 100644 index 00000000000..18fa0acaa9f --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/GoodWeGridMeterCategory.java @@ -0,0 +1,26 @@ +package io.openems.edge.app.integratedsystem; + +import static io.openems.edge.core.appmanager.TranslationUtil.translate; + +import io.openems.common.session.Language; +import io.openems.edge.app.enums.TranslatableEnum; +import io.openems.edge.core.appmanager.AbstractOpenemsApp; + +public enum GoodWeGridMeterCategory implements TranslatableEnum { + SMART_METER("App.IntegratedSystem.gridMeterType.option.smartMeter"), // + COMMERCIAL_METER("App.IntegratedSystem.gridMeterType.option.commercialMeter"), // + ; + + private final String translationKey; + + private GoodWeGridMeterCategory(String translationKey) { + this.translationKey = translationKey; + } + + @Override + public String getTranslation(Language language) { + final var bundle = AbstractOpenemsApp.getTranslationBundle(language); + return translate(bundle, this.translationKey); + } + +} diff --git a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/IntegratedSystemProps.java b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/IntegratedSystemProps.java index db4c4ac2ddc..d5610be64fd 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/IntegratedSystemProps.java +++ b/io.openems.edge.core/src/io/openems/edge/app/integratedsystem/IntegratedSystemProps.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; import java.util.function.Function; import io.openems.edge.app.enums.FeedInType; @@ -16,6 +17,7 @@ import io.openems.edge.core.appmanager.Type.Parameter.BundleProvider; import io.openems.edge.core.appmanager.formly.Exp; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; +import io.openems.edge.core.appmanager.formly.builder.InputBuilder; import io.openems.edge.core.appmanager.formly.expression.BooleanExpression; public final class IntegratedSystemProps { @@ -107,6 +109,51 @@ public static final AppDef feedInSetting() })); } + /** + * Creates a {@link AppDef} for the type of the grid meter. + * + * @return the created {@link AppDef} + */ + public static final AppDef gridMeterType() { + return AppDef.copyOfGeneric(defaultDef(), def -> def // + .setTranslatedLabel("App.IntegratedSystem.gridMeterType.label") // + .setDefaultValue(GoodWeGridMeterCategory.SMART_METER) // + .setField(JsonFormlyUtil::buildSelectFromNameable, (app, property, l, parameter, field) -> { + field.setOptions(OptionsFactory.of(GoodWeGridMeterCategory.class), l); + })); + } + + private static final AppDef ctRatio(// + final Nameable gridMeterType, // + final Consumer fieldSettings // + ) { + return AppDef.copyOfGeneric(defaultDef(), def -> def // + .setField(JsonFormlyUtil::buildInputFromNameable, (app, property, l, parameter, field) -> { + field.onlyShowIf(Exp.currentModelValue(gridMeterType) + .equal(Exp.staticValue(GoodWeGridMeterCategory.COMMERCIAL_METER))); + field.setInputType(NUMBER) // + .setMin(0) // + .onlyPositiveNumbers(); + + fieldSettings.accept(field); + })); + } + + /** + * Creates a {@link AppDef} for the first value of the CT-Ratio. + * + * @param gridMeterType the {@link Nameable} for the type of the grid meter + * @return the created {@link AppDef} + */ + public static final AppDef ctRatioFirst(Nameable gridMeterType) { + return AppDef.copyOfGeneric(ctRatio(gridMeterType, field -> { + field.setMin(200) // + .setMax(5000); + }), def -> def // + .setTranslatedLabel("App.IntegratedSystem.ctRatioFirst.label") // + .setDefaultValue(200)); + } + /** * Creates a {@link AppDef} for selecting if emergency reserve is existing. * diff --git a/io.openems.edge.core/src/io/openems/edge/app/meter/AbstractMeterApp.java b/io.openems.edge.core/src/io/openems/edge/app/meter/AbstractMeterApp.java deleted file mode 100644 index 4824bd319ba..00000000000 --- a/io.openems.edge.core/src/io/openems/edge/app/meter/AbstractMeterApp.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.openems.edge.app.meter; - -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; - -import com.google.gson.JsonArray; - -import io.openems.common.session.Language; -import io.openems.common.utils.JsonUtils; -import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.core.appmanager.AbstractEnumOpenemsApp; -import io.openems.edge.core.appmanager.AbstractOpenemsApp; -import io.openems.edge.core.appmanager.ComponentUtil; -import io.openems.edge.core.appmanager.Nameable; -import io.openems.edge.core.appmanager.OpenemsAppCategory; -import io.openems.edge.core.appmanager.TranslationUtil; - -public abstract class AbstractMeterApp & Nameable> - extends AbstractEnumOpenemsApp { - - protected AbstractMeterApp(ComponentManager componentManager, ComponentContext componentContext, - ConfigurationAdmin cm, ComponentUtil componentUtil) { - super(componentManager, componentContext, cm, componentUtil); - } - - @Override - public final OpenemsAppCategory[] getCategories() { - return new OpenemsAppCategory[] { OpenemsAppCategory.METER }; - } - - protected final JsonArray buildMeterOptions(Language language) { - var bundle = AbstractOpenemsApp.getTranslationBundle(language); - return JsonUtils.buildJsonArray() // - .add(JsonUtils.buildJsonObject() // - .addProperty("label", TranslationUtil.getTranslation(bundle, "App.Meter.production")) // - .addProperty("value", "PRODUCTION") // - .build()) - .add(JsonUtils.buildJsonObject() // - .addProperty("label", TranslationUtil.getTranslation(bundle, "App.Meter.consumtionMeter")) // - .addProperty("value", "CONSUMPTION_METERED") // - .build()) - .build(); - } - -} diff --git a/io.openems.edge.core/src/io/openems/edge/app/meter/CarloGavazziMeter.java b/io.openems.edge.core/src/io/openems/edge/app/meter/CarloGavazziMeter.java index 064957748de..f749dae1f0c 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/meter/CarloGavazziMeter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/meter/CarloGavazziMeter.java @@ -1,6 +1,9 @@ package io.openems.edge.app.meter; -import java.util.EnumMap; +import static io.openems.edge.app.common.props.CommonProps.alias; + +import java.util.Map; +import java.util.function.Function; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; @@ -16,24 +19,29 @@ import io.openems.common.oem.OpenemsEdgeOem; import io.openems.common.session.Language; import io.openems.common.types.EdgeConfig; -import io.openems.common.utils.EnumUtils; import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.common.props.CommunicationProps; +import io.openems.edge.app.common.props.ComponentProps; +import io.openems.edge.app.common.props.PropsUtil; +import io.openems.edge.app.enums.MeterType; import io.openems.edge.app.meter.CarloGavazziMeter.Property; import io.openems.edge.common.component.ComponentManager; import io.openems.edge.core.appmanager.AbstractOpenemsApp; -import io.openems.edge.core.appmanager.AppAssistant; +import io.openems.edge.core.appmanager.AbstractOpenemsAppWithProps; import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppDef; import io.openems.edge.core.appmanager.AppDescriptor; +import io.openems.edge.core.appmanager.AppManagerUtil; +import io.openems.edge.core.appmanager.AppManagerUtilSupplier; import io.openems.edge.core.appmanager.ComponentUtil; import io.openems.edge.core.appmanager.ConfigurationTarget; -import io.openems.edge.core.appmanager.Nameable; import io.openems.edge.core.appmanager.OpenemsApp; import io.openems.edge.core.appmanager.OpenemsAppCardinality; -import io.openems.edge.core.appmanager.TranslationUtil; +import io.openems.edge.core.appmanager.OpenemsAppCategory; +import io.openems.edge.core.appmanager.Type; +import io.openems.edge.core.appmanager.Type.Parameter; +import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; -import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; -import io.openems.edge.core.appmanager.formly.builder.SelectBuilder; -import io.openems.edge.core.appmanager.formly.enums.InputType; /** * Describes a app for a Carlo Gavazzi meter. @@ -56,36 +64,80 @@ * */ @Component(name = "App.Meter.CarloGavazzi") -public class CarloGavazziMeter extends AbstractMeterApp implements OpenemsApp { +public class CarloGavazziMeter + extends AbstractOpenemsAppWithProps + implements OpenemsApp, AppManagerUtilSupplier { - public enum Property implements Nameable { + public enum Property implements Type { // Component-IDs - METER_ID, // + METER_ID(AppDef.componentId("meter0")), // // Properties - ALIAS, // - TYPE, // - MODBUS_ID, // - MODBUS_UNIT_ID, // + ALIAS(alias()), // + TYPE(AppDef.copyOfGeneric(MeterProps.type(MeterType.GRID), def -> def // + .setRequired(true))), // + MODBUS_ID(AppDef.copyOfGeneric(ComponentProps.pickModbusId(), def -> def // + .setRequired(true) // + .wrapField((app, property, l, parameter, field) -> { + if (PropsUtil.isHomeInstalled(app.getAppManagerUtil())) { + field.readonly(true); + } + })) // + .setAutoGenerateField(false)), // + MODBUS_UNIT_ID(AppDef.copyOfGeneric(MeterProps.modbusUnitId(), def -> def // + .setRequired(true) // + .setDefaultValue(6) // + .setAutoGenerateField(false))), // + MODBUS_GROUP(AppDef.copyOfGeneric(CommunicationProps.modbusGroup(// + MODBUS_ID, MODBUS_ID.def(), MODBUS_UNIT_ID, MODBUS_UNIT_ID.def()))), // ; + + private final AppDef def; + + private Property(AppDef def) { + this.def = def; + } + + @Override + public Type self() { + return this; + } + + @Override + public AppDef def() { + return this.def; + } + + @Override + public Function, BundleParameter> getParamter() { + return Parameter.functionOf(AbstractOpenemsApp::getTranslationBundle); + } } + private final AppManagerUtil appManagerUtil; + @Activate - public CarloGavazziMeter(@Reference ComponentManager componentManager, ComponentContext componentContext, - @Reference ConfigurationAdmin cm, @Reference ComponentUtil componentUtil) { + public CarloGavazziMeter(// + @Reference ComponentManager componentManager, // + ComponentContext componentContext, // + @Reference ConfigurationAdmin cm, // + @Reference ComponentUtil componentUtil, // + @Reference AppManagerUtil appManagerUtil // + ) { super(componentManager, componentContext, cm, componentUtil); + this.appManagerUtil = appManagerUtil; } @Override - protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appConfigurationFactory() { + protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { return (t, p, l) -> { - var modbusId = this.getValueOrDefault(p, Property.MODBUS_ID, "modbus1"); - var meterId = this.getId(t, p, Property.METER_ID, "meter1"); + final var meterId = this.getId(t, p, Property.METER_ID); - var alias = this.getValueOrDefault(p, Property.ALIAS, this.getName(l)); - var type = this.getValueOrDefault(p, Property.TYPE, "PRODUCTION"); + final var alias = this.getString(p, l, Property.ALIAS); + final var type = this.getString(p, Property.TYPE); - var modbusUnitId = EnumUtils.getAsInt(p, Property.MODBUS_UNIT_ID); + final var modbusId = this.getString(p, Property.MODBUS_ID); + final var modbusUnitId = this.getInt(p, Property.MODBUS_UNIT_ID); var components = Lists.newArrayList(// new EdgeConfig.Component(meterId, alias, "Meter.CarloGavazzi.EM300", // @@ -102,36 +154,6 @@ protected ThrowingTriFunction getPropertyClass() { - return Property.class; + public OpenemsAppCardinality getCardinality() { + return OpenemsAppCardinality.MULTIPLE; + } + + @Override + public OpenemsAppCategory[] getCategories() { + return new OpenemsAppCategory[] { OpenemsAppCategory.METER }; } @Override - public OpenemsAppCardinality getCardinality() { - return OpenemsAppCardinality.MULTIPLE; + protected CarloGavazziMeter getApp() { + return this; + } + + @Override + protected Property[] propertyValues() { + return Property.values(); + } + + @Override + public AppManagerUtil getAppManagerUtil() { + return this.appManagerUtil; } } diff --git a/io.openems.edge.core/src/io/openems/edge/app/meter/JanitzaMeter.java b/io.openems.edge.core/src/io/openems/edge/app/meter/JanitzaMeter.java index c304af75bee..ac824238ce5 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/meter/JanitzaMeter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/meter/JanitzaMeter.java @@ -119,7 +119,7 @@ public enum Property implements Type def // .setRequired(true) // - .setDefaultValue(7) // + .setDefaultValue(6) // .setAutoGenerateField(false))), // MODBUS_GROUP(AppDef.copyOfGeneric(CommunicationProps.modbusGroup(// MODBUS_ID, MODBUS_ID.def(), MODBUS_UNIT_ID, MODBUS_UNIT_ID.def()))), // diff --git a/io.openems.edge.core/src/io/openems/edge/app/meter/MicrocareSdm630Meter.java b/io.openems.edge.core/src/io/openems/edge/app/meter/MicrocareSdm630Meter.java index a20b7418395..014ed6fd11f 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/meter/MicrocareSdm630Meter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/meter/MicrocareSdm630Meter.java @@ -81,7 +81,7 @@ public enum Property implements Type def // .setRequired(true) // .setAutoGenerateField(false) // - .setDefaultValue(10))), // + .setDefaultValue(6))), // MODBUS_GROUP(CommunicationProps.modbusGroup(MODBUS_ID, MODBUS_ID.def(), // MODBUS_UNIT_ID, MODBUS_UNIT_ID.def())), // UNOFFICIAL_APP_WARNING(CommonProps.installationHintOfUnofficialApp()), // diff --git a/io.openems.edge.core/src/io/openems/edge/app/meter/SocomecMeter.java b/io.openems.edge.core/src/io/openems/edge/app/meter/SocomecMeter.java index c818e1b9d9f..06ecdf33f0e 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/meter/SocomecMeter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/meter/SocomecMeter.java @@ -83,7 +83,7 @@ public enum Property implements Type def // .setRequired(true) // .setAutoGenerateField(false) // - .setDefaultValue(7))), // + .setDefaultValue(6))), // MODBUS_GROUP(AppDef.copyOfGeneric(CommunicationProps.modbusGroup(// MODBUS_ID, MODBUS_ID.def(), MODBUS_UNIT_ID, MODBUS_UNIT_ID.def()))); diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/AbstractPvInverter.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/AbstractPvInverter.java deleted file mode 100644 index aed29b956bd..00000000000 --- a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/AbstractPvInverter.java +++ /dev/null @@ -1,86 +0,0 @@ -package io.openems.edge.app.pvinverter; - -import java.util.List; - -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.component.ComponentContext; - -import com.google.common.collect.Lists; - -import io.openems.common.session.Language; -import io.openems.common.types.EdgeConfig; -import io.openems.common.types.EdgeConfig.Component; -import io.openems.common.utils.JsonUtils; -import io.openems.edge.app.pvinverter.FroniusPvInverter.Property; -import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.core.appmanager.AbstractEnumOpenemsApp; -import io.openems.edge.core.appmanager.AbstractOpenemsApp; -import io.openems.edge.core.appmanager.ComponentUtil; -import io.openems.edge.core.appmanager.Nameable; -import io.openems.edge.core.appmanager.OpenemsAppCategory; -import io.openems.edge.core.appmanager.TranslationUtil; -import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; -import io.openems.edge.core.appmanager.formly.builder.InputBuilder; -import io.openems.edge.core.appmanager.formly.enums.InputType; -import io.openems.edge.core.appmanager.formly.enums.Validation; - -public abstract class AbstractPvInverter & Nameable> - extends AbstractEnumOpenemsApp { - - protected AbstractPvInverter(ComponentManager componentManager, ComponentContext componentContext, - ConfigurationAdmin cm, ComponentUtil componentUtil) { - super(componentManager, componentContext, cm, componentUtil); - } - - @Override - public OpenemsAppCategory[] getCategories() { - return new OpenemsAppCategory[] { OpenemsAppCategory.PV_INVERTER }; - } - - protected final List getComponents(String factoryId, String pvInverterId, // - String modbusId, String alias, String ip, int port) { - return Lists.newArrayList(// - new EdgeConfig.Component(pvInverterId, alias, factoryId, // - JsonUtils.buildJsonObject() // - .addProperty("modbus.id", modbusId) // - .build()), // - new EdgeConfig.Component(modbusId, alias, "Bridge.Modbus.Tcp", JsonUtils.buildJsonObject() // - .addProperty("ip", ip) // - .addProperty("port", port) // - .build())// - ); - } - - protected static > InputBuilder buildIp(Language language, PROPERTY property) { - final var bundle = AbstractOpenemsApp.getTranslationBundle(language); - return JsonFormlyUtil.buildInput(property) // - .setLabel(TranslationUtil.getTranslation(bundle, "communication.ipAddress")) // - .setDescription(TranslationUtil.getTranslation(bundle, "App.PvInverter.ip.description")) // - .setDefaultValue("192.168.178.85") // - .isRequired(true) // - .setValidation(Validation.IP); - } - - protected static > InputBuilder buildPort(Language language, PROPERTY property) { - final var bundle = AbstractOpenemsApp.getTranslationBundle(language); - return JsonFormlyUtil.buildInput(Property.PORT) // - .setLabel(TranslationUtil.getTranslation(bundle, "communication.port")) // - .setDescription(TranslationUtil.getTranslation(bundle, "App.PvInverter.port.description")) // - .setInputType(InputType.NUMBER) // - .setDefaultValue(502) // - .setMin(0) // - .isRequired(true); - } - - protected static > InputBuilder buildModbusUnitId(Language language, - PROPERTY property) { - final var bundle = AbstractOpenemsApp.getTranslationBundle(language); - return JsonFormlyUtil.buildInput(Property.MODBUS_UNIT_ID) // - .setLabel(TranslationUtil.getTranslation(bundle, "communication.modbusUnitId")) // - .setDescription(TranslationUtil.getTranslation(bundle, "App.PvInverter.modbusUnitId.description")) // - .setInputType(InputType.NUMBER) // - .setMin(0) // - .isRequired(true); - } - -} diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/CommonPvInverterConfiguration.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/CommonPvInverterConfiguration.java deleted file mode 100644 index c3932e64c6d..00000000000 --- a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/CommonPvInverterConfiguration.java +++ /dev/null @@ -1,96 +0,0 @@ -package io.openems.edge.app.pvinverter; - -import java.util.List; -import java.util.function.Consumer; - -import com.google.common.collect.Lists; - -import io.openems.common.types.EdgeConfig; -import io.openems.common.types.EdgeConfig.Component; -import io.openems.common.utils.JsonUtils; -import io.openems.common.utils.JsonUtils.JsonObjectBuilder; -import io.openems.edge.app.common.props.CommunicationProps; -import io.openems.edge.core.appmanager.AppDef; -import io.openems.edge.core.appmanager.Nameable; -import io.openems.edge.core.appmanager.OpenemsApp; -import io.openems.edge.core.appmanager.Type.Parameter.BundleProvider; - -public final class CommonPvInverterConfiguration { - - private CommonPvInverterConfiguration() { - } - - /** - * Creates a {@link AppDef} for a PV-Inverter ip-address. - * - * @return the {@link AppDef} - */ - public static final AppDef ip() { - return AppDef.copyOfGeneric(CommunicationProps.ip(), def -> def // - .setTranslatedDescription("App.PvInverter.ip.description")); - } - - /** - * Creates a {@link AppDef} for a PV-Inverter port. - * - * @return the {@link AppDef} - */ - public static final AppDef port() { - return AppDef.copyOfGeneric(CommunicationProps.port(), def -> def // - .setTranslatedDescription("App.PvInverter.port.description")); - } - - /** - * Creates a {@link AppDef} for a PV-Inverter modbusUnitId. - * - * @return the {@link AppDef} - */ - public static final AppDef modbusUnitId() { - return AppDef.copyOfGeneric(CommunicationProps.modbusUnitId(), def -> def // - .setTranslatedDescription("App.PvInverter.modbusUnitId.description")); - } - - /** - * Creates the commonly used components for a PV-Inverter. - * - * @param factoryId the factoryId of the PV-Inverter - * @param pvInverterId the id of the PV-Inverter - * @param modbusId the id of the modbus component - * @param alias the alias of the inverter - * @param ip the ip of the modbus connection - * @param port the port of the modbus connection - * @param additionalInverterProperties consumer for additional configuration for - * the inverter - * @param additionalBridgeProperties consumer for additional configuration for - * the modbus component - * @return the components - */ - public static final List getComponents(// - final String factoryId, // - final String pvInverterId, // - final String modbusId, // - final String alias, // - final String ip, // - final int port, // - final Consumer additionalInverterProperties, // - final Consumer additionalBridgeProperties // - ) { - final var inverterProperties = JsonUtils.buildJsonObject() // - .addProperty("modbus.id", modbusId); - if (additionalInverterProperties != null) { - additionalInverterProperties.accept(inverterProperties); - } - final var bridgeProperties = JsonUtils.buildJsonObject() // - .addProperty("ip", ip) // - .addProperty("port", port); - if (additionalBridgeProperties != null) { - additionalBridgeProperties.accept(bridgeProperties); - } - - return Lists.newArrayList(// - new EdgeConfig.Component(pvInverterId, alias, factoryId, inverterProperties.build()), // - new EdgeConfig.Component(modbusId, alias, "Bridge.Modbus.Tcp", bridgeProperties.build())// - ); - } - -} diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/FroniusPvInverter.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/FroniusPvInverter.java index d188a07375f..86d0406d238 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/FroniusPvInverter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/FroniusPvInverter.java @@ -1,32 +1,39 @@ package io.openems.edge.app.pvinverter; -import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.common.function.ThrowingTriFunction; import io.openems.common.oem.OpenemsEdgeOem; import io.openems.common.session.Language; -import io.openems.common.utils.EnumUtils; +import io.openems.common.types.EdgeConfig; import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.common.props.CommonProps; import io.openems.edge.app.pvinverter.FroniusPvInverter.Property; import io.openems.edge.common.component.ComponentManager; import io.openems.edge.core.appmanager.AbstractOpenemsApp; -import io.openems.edge.core.appmanager.AppAssistant; +import io.openems.edge.core.appmanager.AbstractOpenemsAppWithProps; import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppDef; import io.openems.edge.core.appmanager.AppDescriptor; import io.openems.edge.core.appmanager.ComponentUtil; import io.openems.edge.core.appmanager.ConfigurationTarget; -import io.openems.edge.core.appmanager.Nameable; import io.openems.edge.core.appmanager.OpenemsApp; import io.openems.edge.core.appmanager.OpenemsAppCardinality; +import io.openems.edge.core.appmanager.OpenemsAppCategory; +import io.openems.edge.core.appmanager.Type; +import io.openems.edge.core.appmanager.Type.Parameter; +import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; /** @@ -51,19 +58,42 @@ } * */ -@org.osgi.service.component.annotations.Component(name = "App.PvInverter.Fronius") -public class FroniusPvInverter extends AbstractPvInverter implements OpenemsApp { +@Component(name = "App.PvInverter.Fronius") +public class FroniusPvInverter extends + AbstractOpenemsAppWithProps implements OpenemsApp { - public static enum Property implements Nameable { + public static enum Property implements Type { // Component-IDs - PV_INVERTER_ID, // - MODBUS_ID, // + PV_INVERTER_ID(AppDef.componentId("pvInverter0")), // + MODBUS_ID(AppDef.componentId("modbus0")), // // Properties - ALIAS, // - IP, // - PORT, // - MODBUS_UNIT_ID // + ALIAS(CommonProps.alias()), // + IP(PvInverterProps.ip()), // + PORT(PvInverterProps.port()), // + MODBUS_UNIT_ID(AppDef.copyOfGeneric(PvInverterProps.modbusUnitId(), def -> def// + .setDefaultValue(1))), // ; + + private final AppDef def; + + private Property(AppDef def) { + this.def = def; + } + + @Override + public Type self() { + return this; + } + + @Override + public AppDef def() { + return this.def; + } + + @Override + public Function, BundleParameter> getParamter() { + return Parameter.functionOf(AbstractOpenemsApp::getTranslationBundle); + } } @Activate @@ -73,21 +103,27 @@ public FroniusPvInverter(@Reference ComponentManager componentManager, Component } @Override - protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appConfigurationFactory() { + protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { return (t, p, l) -> { - - var alias = this.getValueOrDefault(p, Property.ALIAS, this.getName(l)); - var ip = this.getValueOrDefault(p, Property.IP, "192.168.178.85"); - var port = EnumUtils.getAsInt(p, Property.PORT); - var modbusUnitId = EnumUtils.getAsInt(p, Property.MODBUS_UNIT_ID); - - var modbusId = this.getId(t, p, Property.MODBUS_ID, "modbus0"); - var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID, "pvInverter0"); - - var factoryIdInverter = "PV-Inverter.Fronius"; - var components = this.getComponents(factoryIdInverter, pvInverterId, modbusId, alias, ip, port); - var inverter = AbstractOpenemsApp.getComponentWithFactoryId(components, factoryIdInverter); - inverter.getProperties().put("modbusUnitId", new JsonPrimitive(modbusUnitId)); + final var modbusId = this.getId(t, p, Property.MODBUS_ID); + final var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID); + + final var alias = this.getString(p, l, Property.ALIAS); + final var ip = this.getString(p, Property.IP); + final var port = this.getInt(p, Property.PORT); + final var modbusUnitId = this.getInt(p, Property.MODBUS_UNIT_ID); + + final var components = List.of(// + new EdgeConfig.Component(pvInverterId, alias, "PV-Inverter.Fronius", // + JsonUtils.buildJsonObject() // + .addProperty("modbus.id", modbusId) // + .addProperty("modbusUnitId", modbusUnitId) // + .build()), // + new EdgeConfig.Component(modbusId, alias, "Bridge.Modbus.Tcp", JsonUtils.buildJsonObject() // + .addProperty("ip", ip) // + .addProperty("port", port) // + .build())// + ); return AppConfiguration.create() // .addTask(Tasks.component(components)) // @@ -95,21 +131,6 @@ protected ThrowingTriFunction getPropertyClass() { - return Property.class; + public OpenemsAppCardinality getCardinality() { + return OpenemsAppCardinality.MULTIPLE; } @Override - public OpenemsAppCardinality getCardinality() { - return OpenemsAppCardinality.MULTIPLE; + public OpenemsAppCategory[] getCategories() { + return new OpenemsAppCategory[] { OpenemsAppCategory.PV_INVERTER }; + } + + @Override + protected FroniusPvInverter getApp() { + return this; + } + + @Override + protected Property[] propertyValues() { + return Property.values(); } } diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KacoPvInverter.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KacoPvInverter.java index b7161f1dfbc..0d2d8418f3e 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KacoPvInverter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KacoPvInverter.java @@ -1,10 +1,13 @@ package io.openems.edge.app.pvinverter; -import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.google.gson.JsonElement; @@ -13,18 +16,24 @@ import io.openems.common.function.ThrowingTriFunction; import io.openems.common.oem.OpenemsEdgeOem; import io.openems.common.session.Language; -import io.openems.common.utils.EnumUtils; +import io.openems.common.types.EdgeConfig; import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.common.props.CommonProps; import io.openems.edge.app.pvinverter.KacoPvInverter.Property; import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.core.appmanager.AppAssistant; +import io.openems.edge.core.appmanager.AbstractOpenemsApp; +import io.openems.edge.core.appmanager.AbstractOpenemsAppWithProps; import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppDef; import io.openems.edge.core.appmanager.AppDescriptor; import io.openems.edge.core.appmanager.ComponentUtil; import io.openems.edge.core.appmanager.ConfigurationTarget; -import io.openems.edge.core.appmanager.Nameable; import io.openems.edge.core.appmanager.OpenemsApp; import io.openems.edge.core.appmanager.OpenemsAppCardinality; +import io.openems.edge.core.appmanager.OpenemsAppCategory; +import io.openems.edge.core.appmanager.Type; +import io.openems.edge.core.appmanager.Type.Parameter; +import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; /** @@ -48,18 +57,40 @@ } * */ -@org.osgi.service.component.annotations.Component(name = "App.PvInverter.Kaco") -public class KacoPvInverter extends AbstractPvInverter implements OpenemsApp { +@Component(name = "App.PvInverter.Kaco") +public class KacoPvInverter extends AbstractOpenemsAppWithProps + implements OpenemsApp { - public static enum Property implements Nameable { + public static enum Property implements Type { // Component-IDs - PV_INVERTER_ID, // - MODBUS_ID, // + PV_INVERTER_ID(AppDef.componentId("pvInverter0")), // + MODBUS_ID(AppDef.componentId("modbus0")), // // Properties - ALIAS, // - IP, // - PORT // + ALIAS(CommonProps.alias()), // + IP(PvInverterProps.ip()), // + PORT(PvInverterProps.port()), // ; + + private final AppDef def; + + private Property(AppDef def) { + this.def = def; + } + + @Override + public Type self() { + return this; + } + + @Override + public AppDef def() { + return this.def; + } + + @Override + public Function, BundleParameter> getParamter() { + return Parameter.functionOf(AbstractOpenemsApp::getTranslationBundle); + } } @Activate @@ -69,18 +100,25 @@ public KacoPvInverter(@Reference ComponentManager componentManager, ComponentCon } @Override - protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appConfigurationFactory() { + protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { return (t, p, l) -> { - - var alias = this.getValueOrDefault(p, Property.ALIAS, this.getName(l)); - var ip = this.getValueOrDefault(p, Property.IP, "192.168.178.85"); - var port = EnumUtils.getAsInt(p, Property.PORT); - - var modbusId = this.getId(t, p, Property.MODBUS_ID, "modbus0"); - var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID, "pvInverter0"); - - var factoryIdInverter = "PV-Inverter.KACO.blueplanet"; - var components = this.getComponents(factoryIdInverter, pvInverterId, modbusId, alias, ip, port); + final var modbusId = this.getId(t, p, Property.MODBUS_ID); + final var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID); + + final var alias = this.getString(p, l, Property.ALIAS); + final var ip = this.getString(p, Property.IP); + final var port = this.getInt(p, Property.PORT); + + final var components = List.of(// + new EdgeConfig.Component(pvInverterId, alias, "PV-Inverter.KACO.blueplanet", // + JsonUtils.buildJsonObject() // + .addProperty("modbus.id", modbusId) // + .build()), // + new EdgeConfig.Component(modbusId, alias, "Bridge.Modbus.Tcp", JsonUtils.buildJsonObject() // + .addProperty("ip", ip) // + .addProperty("port", port) // + .build())// + ); return AppConfiguration.create() // .addTask(Tasks.component(components)) // @@ -88,18 +126,6 @@ protected ThrowingTriFunction getPropertyClass() { - return Property.class; + public OpenemsAppCardinality getCardinality() { + return OpenemsAppCardinality.MULTIPLE; } @Override - public OpenemsAppCardinality getCardinality() { - return OpenemsAppCardinality.MULTIPLE; + public OpenemsAppCategory[] getCategories() { + return new OpenemsAppCategory[] { OpenemsAppCategory.PV_INVERTER }; + } + + @Override + protected KacoPvInverter getApp() { + return this; + } + + @Override + protected Property[] propertyValues() { + return Property.values(); } } diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KostalPvInverter.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KostalPvInverter.java index cf5c916a8e5..5ba6af29654 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KostalPvInverter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/KostalPvInverter.java @@ -1,32 +1,39 @@ package io.openems.edge.app.pvinverter; -import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.google.gson.JsonElement; -import com.google.gson.JsonPrimitive; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.common.function.ThrowingTriFunction; import io.openems.common.oem.OpenemsEdgeOem; import io.openems.common.session.Language; -import io.openems.common.utils.EnumUtils; +import io.openems.common.types.EdgeConfig; import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.common.props.CommonProps; import io.openems.edge.app.pvinverter.KostalPvInverter.Property; import io.openems.edge.common.component.ComponentManager; import io.openems.edge.core.appmanager.AbstractOpenemsApp; -import io.openems.edge.core.appmanager.AppAssistant; +import io.openems.edge.core.appmanager.AbstractOpenemsAppWithProps; import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppDef; import io.openems.edge.core.appmanager.AppDescriptor; import io.openems.edge.core.appmanager.ComponentUtil; import io.openems.edge.core.appmanager.ConfigurationTarget; -import io.openems.edge.core.appmanager.Nameable; import io.openems.edge.core.appmanager.OpenemsApp; import io.openems.edge.core.appmanager.OpenemsAppCardinality; +import io.openems.edge.core.appmanager.OpenemsAppCategory; +import io.openems.edge.core.appmanager.Type; +import io.openems.edge.core.appmanager.Type.Parameter; +import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; /** @@ -51,20 +58,44 @@ } * */ -@org.osgi.service.component.annotations.Component(name = "App.PvInverter.Kostal") -public class KostalPvInverter extends AbstractPvInverter implements OpenemsApp { +@Component(name = "App.PvInverter.Kostal") +public class KostalPvInverter extends AbstractOpenemsAppWithProps + implements OpenemsApp { - public static enum Property implements Nameable { + public static enum Property implements Type { // Component-IDs - PV_INVERTER_ID, // - MODBUS_ID, // + PV_INVERTER_ID(AppDef.componentId("pvInverter0")), // + MODBUS_ID(AppDef.componentId("modbus0")), // // Properties - ALIAS, // - IP, // - PORT, // - MODBUS_UNIT_ID // + ALIAS(CommonProps.alias()), // + IP(PvInverterProps.ip()), // + PORT(AppDef.copyOfGeneric(PvInverterProps.port(), def -> def// + .setDefaultValue(1502))), // + MODBUS_UNIT_ID(AppDef.copyOfGeneric(PvInverterProps.modbusUnitId(), def -> def// + .setDefaultValue(71))), // ; + private final AppDef def; + + private Property(AppDef def) { + this.def = def; + } + + @Override + public Type self() { + return this; + } + + @Override + public AppDef def() { + return this.def; + } + + @Override + public Function, BundleParameter> getParamter() { + return Parameter.functionOf(AbstractOpenemsApp::getTranslationBundle); + } + } @Activate @@ -74,21 +105,27 @@ public KostalPvInverter(@Reference ComponentManager componentManager, ComponentC } @Override - protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appConfigurationFactory() { + protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { return (t, p, l) -> { - - var alias = this.getValueOrDefault(p, Property.ALIAS, this.getName(l)); - var ip = this.getValueOrDefault(p, Property.IP, "192.168.178.85"); - var port = EnumUtils.getAsInt(p, Property.PORT); - var modbusUnitId = EnumUtils.getAsInt(p, Property.MODBUS_UNIT_ID); - - var modbusId = this.getId(t, p, Property.MODBUS_ID, "modbus0"); - var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID, "pvInverter0"); - - var factoryIdInverter = "PV-Inverter.Kostal"; - var components = this.getComponents(factoryIdInverter, pvInverterId, modbusId, alias, ip, port); - var inverter = AbstractOpenemsApp.getComponentWithFactoryId(components, factoryIdInverter); - inverter.getProperties().put("modbusUnitId", new JsonPrimitive(modbusUnitId)); + final var modbusId = this.getId(t, p, Property.MODBUS_ID); + final var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID); + + final var alias = this.getString(p, l, Property.ALIAS); + final var ip = this.getString(p, Property.IP); + final var port = this.getInt(p, Property.PORT); + final var modbusUnitId = this.getInt(p, Property.MODBUS_UNIT_ID); + + final var components = List.of(// + new EdgeConfig.Component(pvInverterId, alias, "PV-Inverter.Kostal", // + JsonUtils.buildJsonObject() // + .addProperty("modbus.id", modbusId) // + .addProperty("modbusUnitId", modbusUnitId) // + .build()), // + new EdgeConfig.Component(modbusId, alias, "Bridge.Modbus.Tcp", JsonUtils.buildJsonObject() // + .addProperty("ip", ip) // + .addProperty("port", port) // + .build())// + ); return AppConfiguration.create() // .addTask(Tasks.component(components)) // @@ -96,22 +133,6 @@ protected ThrowingTriFunction getPropertyClass() { - return Property.class; + public OpenemsAppCardinality getCardinality() { + return OpenemsAppCardinality.MULTIPLE; } @Override - public OpenemsAppCardinality getCardinality() { - return OpenemsAppCardinality.MULTIPLE; + public OpenemsAppCategory[] getCategories() { + return new OpenemsAppCategory[] { OpenemsAppCategory.PV_INVERTER }; + } + + @Override + protected KostalPvInverter getApp() { + return this; + } + + @Override + protected Property[] propertyValues() { + return Property.values(); } } diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/PvInverterProps.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/PvInverterProps.java new file mode 100644 index 00000000000..46803bb7ef4 --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/PvInverterProps.java @@ -0,0 +1,64 @@ +package io.openems.edge.app.pvinverter; + +import static io.openems.edge.app.common.props.CommonProps.defaultDef; + +import io.openems.edge.app.common.props.CommunicationProps; +import io.openems.edge.app.enums.OptionsFactory; +import io.openems.edge.app.enums.Phase; +import io.openems.edge.core.appmanager.AppDef; +import io.openems.edge.core.appmanager.Nameable; +import io.openems.edge.core.appmanager.OpenemsApp; +import io.openems.edge.core.appmanager.Type.Parameter.BundleProvider; +import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; + +public final class PvInverterProps { + + /** + * Creates a {@link AppDef} for a PV-Inverter ip-address. + * + * @return the {@link AppDef} + */ + public static final AppDef ip() { + return AppDef.copyOfGeneric(CommunicationProps.ip(), def -> def // + .setTranslatedDescription("App.PvInverter.ip.description")); + } + + /** + * Creates a {@link AppDef} for a PV-Inverter port. + * + * @return the {@link AppDef} + */ + public static final AppDef port() { + return AppDef.copyOfGeneric(CommunicationProps.port(), def -> def // + .setTranslatedDescription("App.PvInverter.port.description")); + } + + /** + * Creates a {@link AppDef} for a PV-Inverter modbusUnitId. + * + * @return the {@link AppDef} + */ + public static final AppDef modbusUnitId() { + return AppDef.copyOfGeneric(CommunicationProps.modbusUnitId(), def -> def // + .setTranslatedDescription("App.PvInverter.modbusUnitId.description")); + } + + /** + * Creates a {@link AppDef} for a PV-Inverter phase selection. + * + * @return the {@link AppDef} + */ + public static final AppDef phase() { + return AppDef.copyOfGeneric(defaultDef(), def -> def // + .setTranslatedLabel("App.PvInverter.phase.label") // + .setTranslatedDescription("App.PvInverter.phase.description") // + .setDefaultValue(Phase.ALL) // + .setField(JsonFormlyUtil::buildSelectFromNameable, (app, property, l, parameter, field) -> { + field.setOptions(OptionsFactory.of(Phase.class), l); + })); + } + + private PvInverterProps() { + } + +} diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SmaPvInverter.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SmaPvInverter.java index 24c467188cb..55de1d9582a 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SmaPvInverter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SmaPvInverter.java @@ -1,13 +1,13 @@ package io.openems.edge.app.pvinverter; -import static io.openems.edge.app.common.props.CommonProps.alias; - +import java.util.List; import java.util.Map; import java.util.function.Function; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.google.gson.JsonElement; @@ -16,7 +16,9 @@ import io.openems.common.function.ThrowingTriFunction; import io.openems.common.oem.OpenemsEdgeOem; import io.openems.common.session.Language; -import io.openems.edge.app.enums.OptionsFactory; +import io.openems.common.types.EdgeConfig; +import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.common.props.CommonProps; import io.openems.edge.app.enums.Phase; import io.openems.edge.app.pvinverter.SmaPvInverter.Property; import io.openems.edge.common.component.ComponentManager; @@ -36,7 +38,6 @@ import io.openems.edge.core.appmanager.Type.Parameter; import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; -import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; /** * Describes a App for SMA PV-Inverter. @@ -60,7 +61,7 @@ } * */ -@org.osgi.service.component.annotations.Component(name = "App.PvInverter.Sma") +@Component(name = "App.PvInverter.Sma") public class SmaPvInverter extends AbstractOpenemsAppWithProps implements OpenemsApp { @@ -71,23 +72,17 @@ public static enum Property implements Type def // + ALIAS(CommonProps.alias()), // + IP(AppDef.copyOfGeneric(PvInverterProps.ip(), def -> def // .setRequired(true))), // - PORT(AppDef.copyOfGeneric(CommonPvInverterConfiguration.port(), def -> def // + PORT(AppDef.copyOfGeneric(PvInverterProps.port(), def -> def // .setRequired(true))), // - MODBUS_UNIT_ID(AppDef.copyOfGeneric(CommonPvInverterConfiguration.modbusUnitId(), def -> def // + MODBUS_UNIT_ID(AppDef.copyOfGeneric(PvInverterProps.modbusUnitId(), def -> def // .setTranslatedDescriptionWithAppPrefix(".modbusUnitId.description") // .setRequired(true))), // - PHASE(AppDef.of(SmaPvInverter.class) // - .setTranslatedLabelWithAppPrefix(".phase.label") // ) - .setTranslatedDescriptionWithAppPrefix(".phase.description") // - .setDefaultValue(Phase.ALL.name()) // - .setRequired(true) // - .setField(JsonFormlyUtil::buildSelect, (app, property, l, parameter, field) -> { - field.setOptions(OptionsFactory.of(Phase.class), l); - }) // - .bidirectional(PV_INVERTER_ID, "phase", ComponentManagerSupplier::getComponentManager)); + PHASE(AppDef.copyOfGeneric(PvInverterProps.phase(), def -> def// + .bidirectional(PV_INVERTER_ID, "phase", ComponentManagerSupplier::getComponentManager))), // + ; private final AppDef def; @@ -129,12 +124,18 @@ protected ThrowingTriFunction, L final var modbusId = this.getId(t, p, Property.MODBUS_ID); final var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID); - final var factoryIdInverter = "PV-Inverter.SMA.SunnyTripower"; - final var components = CommonPvInverterConfiguration.getComponents(// - factoryIdInverter, pvInverterId, modbusId, alias, ip, port, - b -> b.addProperty("modbusUnitId", modbusUnitId) // - .addProperty("phase", phase), - null); + final var components = List.of(// + new EdgeConfig.Component(pvInverterId, alias, "PV-Inverter.SMA.SunnyTripower", // + JsonUtils.buildJsonObject() // + .addProperty("modbus.id", modbusId) // + .addProperty("modbusUnitId", modbusUnitId) // + .addProperty("phase", phase) // + .build()), // + new EdgeConfig.Component(modbusId, alias, "Bridge.Modbus.Tcp", JsonUtils.buildJsonObject() // + .addProperty("ip", ip) // + .addProperty("port", port) // + .build())// + ); return AppConfiguration.create() // .addTask(Tasks.component(components)) // diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SolarEdgePvInverter.java b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SolarEdgePvInverter.java index 2a6454b5b83..bd59d5b8a38 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SolarEdgePvInverter.java +++ b/io.openems.edge.core/src/io/openems/edge/app/pvinverter/SolarEdgePvInverter.java @@ -1,10 +1,13 @@ package io.openems.edge.app.pvinverter; -import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import com.google.gson.JsonElement; @@ -13,18 +16,26 @@ import io.openems.common.function.ThrowingTriFunction; import io.openems.common.oem.OpenemsEdgeOem; import io.openems.common.session.Language; -import io.openems.common.utils.EnumUtils; +import io.openems.common.types.EdgeConfig; import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.common.props.CommonProps; +import io.openems.edge.app.enums.Phase; import io.openems.edge.app.pvinverter.SolarEdgePvInverter.Property; import io.openems.edge.common.component.ComponentManager; -import io.openems.edge.core.appmanager.AppAssistant; +import io.openems.edge.core.appmanager.AbstractOpenemsApp; +import io.openems.edge.core.appmanager.AbstractOpenemsAppWithProps; import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppDef; import io.openems.edge.core.appmanager.AppDescriptor; +import io.openems.edge.core.appmanager.ComponentManagerSupplier; import io.openems.edge.core.appmanager.ComponentUtil; import io.openems.edge.core.appmanager.ConfigurationTarget; -import io.openems.edge.core.appmanager.Nameable; import io.openems.edge.core.appmanager.OpenemsApp; import io.openems.edge.core.appmanager.OpenemsAppCardinality; +import io.openems.edge.core.appmanager.OpenemsAppCategory; +import io.openems.edge.core.appmanager.Type; +import io.openems.edge.core.appmanager.Type.Parameter; +import io.openems.edge.core.appmanager.Type.Parameter.BundleParameter; import io.openems.edge.core.appmanager.dependency.Tasks; /** @@ -40,7 +51,8 @@ "PV_INVERTER_ID": "pvInverter0", "MODBUS_ID": "modbus0", "IP": "192.168.178.85", - "PORT": "502" + "PORT": "502", + "PHASE": {@link Phase}, }, "appDescriptor": { "websiteUrl": {@link AppDescriptor#getWebsiteUrl()} @@ -48,19 +60,43 @@ } * */ -@org.osgi.service.component.annotations.Component(name = "App.PvInverter.SolarEdge") -public class SolarEdgePvInverter extends AbstractPvInverter implements OpenemsApp { +@Component(name = "App.PvInverter.SolarEdge") +public class SolarEdgePvInverter extends + AbstractOpenemsAppWithProps implements OpenemsApp { - public static enum Property implements Nameable { + public static enum Property implements Type { // Component-IDs - PV_INVERTER_ID, // - MODBUS_ID, // + PV_INVERTER_ID(AppDef.componentId("pvInverter0")), // + MODBUS_ID(AppDef.componentId("modbus0")), // // Properties - ALIAS, // - PORT, // - IP, // + ALIAS(CommonProps.alias()), // + IP(PvInverterProps.ip()), // + PORT(PvInverterProps.port()), // + PHASE(AppDef.copyOfGeneric(PvInverterProps.phase(), def -> def// + .bidirectional(PV_INVERTER_ID, "phase", ComponentManagerSupplier::getComponentManager))), // ; + private final AppDef def; + + private Property(AppDef def) { + this.def = def; + } + + @Override + public Type self() { + return this; + } + + @Override + public AppDef def() { + return this.def; + } + + @Override + public Function, BundleParameter> getParamter() { + return Parameter.functionOf(AbstractOpenemsApp::getTranslationBundle); + } + } @Activate @@ -70,18 +106,27 @@ public SolarEdgePvInverter(@Reference ComponentManager componentManager, Compone } @Override - protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appConfigurationFactory() { + protected ThrowingTriFunction, Language, AppConfiguration, OpenemsNamedException> appPropertyConfigurationFactory() { return (t, p, l) -> { - - var alias = this.getValueOrDefault(p, Property.ALIAS, this.getName(l)); - var ip = this.getValueOrDefault(p, Property.IP, "192.168.178.85"); - var port = EnumUtils.getAsInt(p, Property.PORT); - - var modbusId = this.getId(t, p, Property.MODBUS_ID, "modbus0"); - var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID, "pvInverter0"); - - var factoryIdInverter = "SolarEdge.PV-Inverter"; - var components = this.getComponents(factoryIdInverter, pvInverterId, modbusId, alias, ip, port); + final var modbusId = this.getId(t, p, Property.MODBUS_ID); + final var pvInverterId = this.getId(t, p, Property.PV_INVERTER_ID); + + final var alias = this.getString(p, l, Property.ALIAS); + final var ip = this.getString(p, Property.IP); + final var port = this.getInt(p, Property.PORT); + final var phase = this.getString(p, Property.PHASE); + + final var components = List.of(// + new EdgeConfig.Component(pvInverterId, alias, "SolarEdge.PV-Inverter", // + JsonUtils.buildJsonObject() // + .addProperty("modbus.id", modbusId) // + .addProperty("phase", phase) // + .build()), // + new EdgeConfig.Component(modbusId, alias, "Bridge.Modbus.Tcp", JsonUtils.buildJsonObject() // + .addProperty("ip", ip) // + .addProperty("port", port) // + .build())// + ); return AppConfiguration.create() // .addTask(Tasks.component(components)) // @@ -89,18 +134,6 @@ protected ThrowingTriFunction getPropertyClass() { - return Property.class; + public OpenemsAppCardinality getCardinality() { + return OpenemsAppCardinality.MULTIPLE; } @Override - public OpenemsAppCardinality getCardinality() { - return OpenemsAppCardinality.MULTIPLE; + protected Property[] propertyValues() { + return Property.values(); + } + + @Override + public OpenemsAppCategory[] getCategories() { + return new OpenemsAppCategory[] { OpenemsAppCategory.PV_INVERTER }; + } + + @Override + protected SolarEdgePvInverter getApp() { + return this; } } diff --git a/io.openems.edge.core/src/io/openems/edge/app/pvselfconsumption/GridOptimizedCharge.java b/io.openems.edge.core/src/io/openems/edge/app/pvselfconsumption/GridOptimizedCharge.java index e5f352f8277..61a97d32e28 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/pvselfconsumption/GridOptimizedCharge.java +++ b/io.openems.edge.core/src/io/openems/edge/app/pvselfconsumption/GridOptimizedCharge.java @@ -37,6 +37,7 @@ import io.openems.edge.core.appmanager.OpenemsAppCategory; import io.openems.edge.core.appmanager.TranslationUtil; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.Exp; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; import io.openems.edge.core.appmanager.formly.enums.InputType; @@ -115,11 +116,11 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEssTimeOfUseTariffId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEssTimeOfUseTariffId, + "Controller.Ess.Time-Of-Use-Tariff", this.getAppId()))) // .addTask(Tasks.persistencePredictor("_sum/UnmanagedConsumptionActivePower")) // .build(); }; @@ -161,6 +165,12 @@ public OpenemsAppCardinality getCardinality() { return OpenemsAppCardinality.SINGLE_IN_CATEGORY; } + @Override + protected ValidatorConfig.Builder getValidateBuilder() { + return ValidatorConfig.create() // + .setCompatibleCheckableConfigs(checkHome()); + } + @Override protected AwattarHourly getApp() { return this; diff --git a/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/EntsoE.java b/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/EntsoE.java index 684322d95cc..cb773d1e584 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/EntsoE.java +++ b/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/EntsoE.java @@ -1,5 +1,7 @@ package io.openems.edge.app.timeofusetariff; +import static io.openems.edge.core.appmanager.validator.Checkables.checkHome; + import java.util.Map; import java.util.function.Function; @@ -36,7 +38,9 @@ import io.openems.edge.core.appmanager.TranslationUtil; import io.openems.edge.core.appmanager.Type; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; +import io.openems.edge.core.appmanager.validator.ValidatorConfig; /** * Describes a App for ENTSO-E. @@ -130,7 +134,8 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEssTimeOfUseTariffId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEssTimeOfUseTariffId, + "Controller.Ess.Time-Of-Use-Tariff", this.getAppId()))) // .addTask(Tasks.persistencePredictor("_sum/UnmanagedConsumptionActivePower")) // .build(); }; @@ -158,6 +163,12 @@ public OpenemsAppCardinality getCardinality() { return OpenemsAppCardinality.SINGLE_IN_CATEGORY; } + @Override + protected ValidatorConfig.Builder getValidateBuilder() { + return ValidatorConfig.create() // + .setCompatibleCheckableConfigs(checkHome()); + } + @Override protected EntsoE getApp() { return this; diff --git a/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/StromdaoCorrently.java b/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/StromdaoCorrently.java index be21ecf87e0..61521495bca 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/StromdaoCorrently.java +++ b/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/StromdaoCorrently.java @@ -1,5 +1,7 @@ package io.openems.edge.app.timeofusetariff; +import static io.openems.edge.core.appmanager.validator.Checkables.checkHome; + import java.util.Map; import java.util.function.Function; @@ -33,8 +35,10 @@ import io.openems.edge.core.appmanager.OpenemsAppCategory; import io.openems.edge.core.appmanager.Type; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; import io.openems.edge.core.appmanager.formly.enums.InputType; +import io.openems.edge.core.appmanager.validator.ValidatorConfig; /** * Describes a App for StromdaoCorrently. @@ -126,7 +130,8 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEssTimeOfUseTariffId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEssTimeOfUseTariffId, + "Controller.Ess.Time-Of-Use-Tariff", this.getAppId()))) // .addTask(Tasks.persistencePredictor("_sum/UnmanagedConsumptionActivePower")) // .build(); }; @@ -154,6 +159,12 @@ public OpenemsAppCardinality getCardinality() { return OpenemsAppCardinality.SINGLE_IN_CATEGORY; } + @Override + protected ValidatorConfig.Builder getValidateBuilder() { + return ValidatorConfig.create() // + .setCompatibleCheckableConfigs(checkHome()); + } + @Override protected StromdaoCorrently getApp() { return this; diff --git a/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/Tibber.java b/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/Tibber.java index 462ab45cbae..34096b0ea79 100644 --- a/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/Tibber.java +++ b/io.openems.edge.core/src/io/openems/edge/app/timeofusetariff/Tibber.java @@ -1,6 +1,7 @@ package io.openems.edge.app.timeofusetariff; import static io.openems.edge.core.appmanager.formly.enums.InputType.PASSWORD; +import static io.openems.edge.core.appmanager.validator.Checkables.checkHome; import java.util.Map; import java.util.function.Function; @@ -38,7 +39,9 @@ import io.openems.edge.core.appmanager.OpenemsAppCategory; import io.openems.edge.core.appmanager.Type; import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.formly.JsonFormlyUtil; +import io.openems.edge.core.appmanager.validator.ValidatorConfig; /** * Describes a App for Tibber. @@ -145,7 +148,8 @@ protected ThrowingTriFunction, L return AppConfiguration.create() // .addTask(Tasks.component(components)) // - .addTask(Tasks.scheduler(ctrlEssTimeOfUseTariffId, "ctrlBalancing0")) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent(ctrlEssTimeOfUseTariffId, + "Controller.Ess.Time-Of-Use-Tariff", this.getAppId()))) // .addTask(Tasks.persistencePredictor("_sum/UnmanagedConsumptionActivePower")) // .build(); }; @@ -173,6 +177,12 @@ public OpenemsAppCardinality getCardinality() { return OpenemsAppCardinality.SINGLE_IN_CATEGORY; } + @Override + protected ValidatorConfig.Builder getValidateBuilder() { + return ValidatorConfig.create() // + .setCompatibleCheckableConfigs(checkHome()); + } + @Override protected Tibber getApp() { return this; diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtil.java b/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtil.java index 6bc3d7c6a3b..0ff8f414d71 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtil.java +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtil.java @@ -293,6 +293,15 @@ public void updateScheduler(User user, List schedulerExecutionOrder, Lis */ public void removeIdsInSchedulerIfExisting(User user, List removedIds) throws OpenemsNamedException; + /** + * Directly 1-to-1 sets the given ids as the scheduler ids. + * + * @param user the executing user + * @param componentIds the scheduler ids + * @throws OpenemsNamedException when the scheduler can not be updated + */ + public void setSchedulerComponentIds(User user, List componentIds) throws OpenemsNamedException; + /** * Gets the current id's in the scheduler. * diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtilImpl.java b/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtilImpl.java index 0d287e0c051..2cc1648bc68 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtilImpl.java +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/ComponentUtilImpl.java @@ -1,21 +1,16 @@ package io.openems.edge.core.appmanager; +import static io.openems.common.utils.JsonUtils.toJsonArray; import static java.util.Collections.emptyList; -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collections; import java.util.Dictionary; import java.util.Enumeration; -import java.util.HashSet; -import java.util.Hashtable; import java.util.List; import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.BiFunction; @@ -28,19 +23,17 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; -import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Reference; -import com.google.common.collect.Lists; -import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; -import io.openems.common.OpenemsConstants; import io.openems.common.exceptions.InvalidValueException; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.common.exceptions.OpenemsException; +import io.openems.common.jsonrpc.request.UpdateComponentConfigRequest; import io.openems.common.types.EdgeConfig; import io.openems.common.types.EdgeConfig.Component; import io.openems.common.utils.JsonUtils; @@ -50,6 +43,7 @@ import io.openems.edge.common.host.Host; import io.openems.edge.common.jsonapi.JsonApi; import io.openems.edge.common.user.User; +import io.openems.edge.core.componentmanager.ComponentManagerImpl; import io.openems.edge.core.host.NetworkInterface; import io.openems.edge.core.host.jsonrpc.SetNetworkConfigRequest; import io.openems.edge.io.api.DigitalOutput; @@ -58,12 +52,10 @@ public class ComponentUtilImpl implements ComponentUtil { private final ComponentManager componentManager; - private final ConfigurationAdmin cm; @Activate - public ComponentUtilImpl(@Reference ComponentManager componentManager, @Reference ConfigurationAdmin cm) { + public ComponentUtilImpl(@Reference ComponentManager componentManager) { this.componentManager = componentManager; - this.cm = cm; } /** @@ -583,7 +575,7 @@ public synchronized void updateScheduler(User user, List schedulerExecut } // get current order - var controllerIds = this.getSchedulerIds(); + var controllerIds = new ArrayList<>(this.getSchedulerIds()); // remove existing id s in the scheduler and insert them in the right place controllerIds.removeAll(schedulerExecutionOrder); @@ -597,68 +589,71 @@ public void removeIdsInSchedulerIfExisting(User user, List removedIds) t if (removedIds == null || removedIds.isEmpty()) { return; } - var controllerIds = this.getSchedulerIds(); + var controllerIds = new ArrayList<>(this.getSchedulerIds()); controllerIds.removeAll(removedIds); this.setSchedulerComponentIds(user, controllerIds); } - private void setSchedulerComponentIds(User user, List componentIds) throws OpenemsNamedException { + @Override + public synchronized void setSchedulerComponentIds(// + final User user, // + final List componentIds // + ) throws OpenemsNamedException { try { - var scheduler = this.getScheduler(); - // null is necessary otherwise a new configuration gets created - var config = this.cm.getConfiguration(scheduler.getPid(), null); - - var properties = config.getProperties(); - if (properties == null) { - // No configuration existing yet -> create new configuration - properties = new Hashtable<>(); - } else { - // configuration exists -> update configuration - } + final var scheduler = this.getScheduler(); - var existingIds = JsonUtils - .getAsJsonArray(scheduler.getProperty("controllers.ids").orElse(new JsonArray())); + final var existingIds = getSchedulerIds(scheduler); // check if the ids in the scheduler are the exact same as given if (existingIds.size() == componentIds.size()) { - Set newIds = new HashSet<>(componentIds); - for (var item : existingIds) { - newIds.remove(JsonUtils.getAsString(item)); + final var schedulerIdIterator = existingIds.iterator(); + var hasChanges = false; + for (var id : componentIds) { + final var schedulerId = schedulerIdIterator.next(); + + if (!id.equals(schedulerId)) { + hasChanges = true; + break; + } } - if (newIds.isEmpty()) { + + if (!hasChanges) { return; } } - var ids = componentIds.stream().toArray(String[]::new); - properties.put("controllers.ids", ids); + var ids = componentIds.stream().map(JsonPrimitive::new).collect(toJsonArray()); + final var request = new UpdateComponentConfigRequest(scheduler.getId(), List.of(// + new UpdateComponentConfigRequest.Property("controllers.ids", ids) // + )); if (user != null) { - properties.put(OpenemsConstants.PROPERTY_LAST_CHANGE_BY, user.getId() + ": " + user.getName()); + this.componentManager.handleJsonrpcRequest(user, request).get(); + return; } - properties.put(OpenemsConstants.PROPERTY_LAST_CHANGE_AT, - LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS).toString()); - config.update(properties); - } catch (IOException e) { + ((ComponentManagerImpl) this.componentManager).handleUpdateComponentConfigRequest(user, request).get(); + } catch (Exception e) { + e.printStackTrace(); throw new OpenemsException("Could not update Scheduler!"); } } @Override public List getSchedulerIds() throws OpenemsNamedException { - try { - final var config = this.cm.getConfiguration(this.getScheduler().getPid(), null); - final var properties = config.getProperties(); - if (properties == null) { - return emptyList(); - } - final var ids = properties.get("controllers.ids"); - return ids == null ? emptyList() : Lists.newArrayList((String[]) ids); - } catch (IOException e) { - throw new OpenemsException("Unable to get Scheduler configuration!", e); - } + return getSchedulerIds(this.getScheduler()); + } + + private static List getSchedulerIds(Component scheduler) throws OpenemsNamedException { + return scheduler.getProperty("controllers.ids") // + .flatMap(JsonUtils::getAsOptionalJsonArray) // + .map(t -> JsonUtils.stream(t) // + .map(JsonUtils::getAsOptionalString) // + .map(c -> c.orElse(null)) // + .filter(Objects::nonNull) // + .toList()) // + .orElse(emptyList()); } @Override diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/Tasks.java b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/Tasks.java index 29be31efe81..8725d33b670 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/Tasks.java +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/Tasks.java @@ -12,6 +12,9 @@ import io.openems.edge.core.appmanager.dependency.aggregatetask.PersistencePredictorAggregateTask; import io.openems.edge.core.appmanager.dependency.aggregatetask.PersistencePredictorConfiguration; import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerAggregateTask; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderAggregateTask; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerConfiguration; import io.openems.edge.core.appmanager.dependency.aggregatetask.StaticIpAggregateTask; import io.openems.edge.core.appmanager.dependency.aggregatetask.StaticIpConfiguration; @@ -78,6 +81,30 @@ public static Task scheduler(String... componentOrder) { return createTask(SchedulerAggregateTask.class, new SchedulerConfiguration(componentOrder)); } + /** + * Creates a Task for setting the {@link SchedulerByCentralOrderConfiguration}. + * + * @param componentOrder the order of the components in the scheduler + * @return the {@link Task} to run when creating the {@link OpenemsAppInstance} + */ + public static Task schedulerByCentralOrder( + List componentOrder) { + return createTask(SchedulerByCentralOrderAggregateTask.class, + new SchedulerByCentralOrderConfiguration(componentOrder)); + } + + /** + * Creates a Task for setting the {@link SchedulerByCentralOrderConfiguration}. + * + * @param componentOrder the order of the components in the scheduler + * @return the {@link Task} to run when creating the {@link OpenemsAppInstance} + */ + public static Task schedulerByCentralOrder( + SchedulerComponent... componentOrder) { + return createTask(SchedulerByCentralOrderAggregateTask.class, + new SchedulerByCentralOrderConfiguration(componentOrder)); + } + /** * Creates a Task for setting the {@link PersistencePredictorConfiguration}. * diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImpl.java b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImpl.java index 1f768653eca..2059bc85e89 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImpl.java +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImpl.java @@ -68,7 +68,8 @@ public void aggregate(// @Override public void create(User user, List otherAppConfigurations) throws OpenemsNamedException { - if (!this.anyChanges()) { + if (!this.anyCreateChanges()) { + this.delete(user, otherAppConfigurations); return; } this.order = this.componentUtil.insertSchedulerOrder(this.componentUtil.getSchedulerIds(), this.order); @@ -79,7 +80,7 @@ public void create(User user, List otherAppConfigurations) thr @Override public void delete(User user, List otherAppConfigurations) throws OpenemsNamedException { - if (!this.anyChanges()) { + if (!this.anyDeleteChanges()) { return; } var otherIds = AppConfiguration @@ -141,10 +142,12 @@ public void validate(List errors, AppConfiguration appConfiguration, Sch } } - private boolean anyChanges() { - return !this.order.isEmpty() // - || !this.removeIds.isEmpty() // - || !this.aggregateTask.getDeletedComponents().isEmpty(); + private boolean anyCreateChanges() { + return !this.order.isEmpty(); + } + + private boolean anyDeleteChanges() { + return !this.removeIds.isEmpty(); } } diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTask.java b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTask.java new file mode 100644 index 00000000000..5345d27f135 --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTask.java @@ -0,0 +1,5 @@ +package io.openems.edge.core.appmanager.dependency.aggregatetask; + +public interface SchedulerByCentralOrderAggregateTask extends AggregateTask { + +} \ No newline at end of file diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImpl.java b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImpl.java new file mode 100644 index 00000000000..05c4bfabdb2 --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImpl.java @@ -0,0 +1,542 @@ +package io.openems.edge.core.appmanager.dependency.aggregatetask; + +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeSet; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ServiceScope; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.exceptions.OpenemsException; +import io.openems.common.session.Language; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.common.user.User; +import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppManagerUtil; +import io.openems.edge.core.appmanager.ComponentUtil; +import io.openems.edge.core.appmanager.ConfigurationTarget; +import io.openems.edge.core.appmanager.OpenemsAppInstance; +import io.openems.edge.core.appmanager.TranslationUtil; +import io.openems.edge.core.appmanager.dependency.AppManagerAppHelperImpl; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; + +@Component(// + service = { // + AggregateTask.class, // + SchedulerByCentralOrderAggregateTask.class, // + SchedulerByCentralOrderAggregateTaskImpl.class // + }, // + scope = ServiceScope.SINGLETON // +) +public class SchedulerByCentralOrderAggregateTaskImpl implements SchedulerByCentralOrderAggregateTask { + + private final ComponentManager componentManager; + private final ComponentUtil componentUtil; + private final AppManagerUtil appManagerUtil; + private final ComponentAggregateTask aggregateTask; + + private final SchedulerOrderDefinition order; + + private List schedulerComponents; + private List removeSchedulerComponents; + + @Component(service = SchedulerOrderDefinition.class) + public static final class ProductionSchedulerOrderDefinition extends SchedulerOrderDefinition { + + public ProductionSchedulerOrderDefinition() { + this.thenByFactoryId("Controller.Ess.PrepareBatteryExtension") // + .thenByFactoryId("Controller.Ess.FixActivePower") // + .thenByFactoryId("Controller.Ess.EmergencyCapacityReserve") // + .thenBy(new SchedulerOrderDefinition() // + .filterByFactoryId("Controller.Api.ModbusTcp.ReadWrite") // + .thenByCreatedAppId("App.Ess.GeneratingPlantController") // + .rest()) // + .thenByFactoryId("Controller.Api.Rest.ReadWrite") // + .thenByFactoryId("Controller.Ess.GridOptimizedCharge") // + .thenByFactoryId("Controller.Ess.Hybrid.Surplus-Feed-To-Grid") // + .thenByFactoryId("Controller.Evcs") // + .thenByFactoryId("Controller.Ess.Time-Of-Use-Tariff") // + .thenByFactoryId("Controller.Symmetric.Balancing") // + ; + } + + } + + @Activate + public SchedulerByCentralOrderAggregateTaskImpl(// + @Reference ComponentManager componentManager, // + @Reference ComponentUtil componentUtil, // + @Reference AppManagerUtil appManagerUtil, // + @Reference ComponentAggregateTask aggregateTask, // + @Reference SchedulerOrderDefinition schedulerOrderDefinition // + ) { + this.componentManager = componentManager; + this.componentUtil = componentUtil; + this.aggregateTask = aggregateTask; + this.appManagerUtil = appManagerUtil; + this.order = schedulerOrderDefinition; + } + + public static class SchedulerOrderDefinition implements Comparator { + + private static final int[] EMPTY_INT_ARRAY = new int[0]; + + private static sealed class PositionReturnType { + + public static final PositionReturnType right(int... index) { + return new Right(index); + } + + public static final PositionReturnType remove() { + return Remove.INSTANCE; + } + + public static final PositionReturnType next() { + return Next.INSTANCE; + } + + public static final class Right extends PositionReturnType { + public final int[] index; + + public Right(int[] index) { + this.index = index; + } + + } + + private static final class Remove extends PositionReturnType { + + public static final Remove INSTANCE = new Remove(); + + } + + private static final class Next extends PositionReturnType { + + public static final Next INSTANCE = new Next(); + + } + + } + + private final List> predicates = new LinkedList<>(); + + /** + * Adds a filter to the order queue which sorts out every + * {@link SchedulerComponent} which does not match the {@link Predicate}. + * + * @param matcher the predicate to determine if the current + * {@link SchedulerComponent} should be filtered out or not; true + * for continuing to next check; false for removing the + * {@link SchedulerComponent} + * @return this + */ + public SchedulerOrderDefinition filterBy(Predicate matcher) { + return this.thenByFunction(t -> matcher.test(t) ? PositionReturnType.next() : PositionReturnType.remove()); + } + + /** + * Adds a filter to the order queue which sorts out every + * {@link SchedulerComponent} which does not match the factoryId. + * + * @param factoryId the factoryId to determine if the current + * {@link SchedulerComponent} should be filtered out or not; + * same for continuing to next check; different for removing + * the {@link SchedulerComponent} + * @return this + */ + public SchedulerOrderDefinition filterByFactoryId(String factoryId) { + return this.filterBy(t -> factoryId.equals(t.factoryId())); + } + + private SchedulerOrderDefinition thenByFunction(Function matcher) { + this.predicates.add(t -> matcher.apply(t)); + return this; + } + + /** + * Adds a matching function if the current {@link SchedulerComponent} is at the + * right position. + * + * @param matcher the predicate if the current {@link SchedulerComponent} is at + * the right position; true if the {@link SchedulerComponent} is + * at the right position; false if the {@link SchedulerComponent} + * should continue to the next function + * @return this + */ + public SchedulerOrderDefinition thenBy(Predicate matcher) { + return this.thenByFunction(t -> matcher.test(t) ? PositionReturnType.right(1) : PositionReturnType.next()); + } + + /** + * Adds a Sub-Order at the current position. + * + * @param order the Sub-Order + * @return this + */ + public SchedulerOrderDefinition thenBy(SchedulerOrderDefinition order) { + return this.thenByFunction(t -> { + final var result = order.indexOfMatch(t); + if (result.length == 0) { + return PositionReturnType.next(); + } + return PositionReturnType.right(result); + }); + } + + /** + * Adds a matching function if the current {@link SchedulerComponent} matches + * the factoryId. + * + * @param factoryId the factoryId if the current {@link SchedulerComponent} has + * the same factoryId it is inserted at this position; + * otherwise the {@link SchedulerComponent} continues to the + * next function should continue to the next function + * @return this + */ + public SchedulerOrderDefinition thenByFactoryId(String factoryId) { + return this.thenBy(t -> factoryId.equals(t.factoryId())); + } + + /** + * Adds a matching function if the current {@link SchedulerComponent} matches + * the appId. right position. + * + * @param appId the appId if the current {@link SchedulerComponent} has the same + * appId it is inserted at this position; otherwise the + * {@link SchedulerComponent} continues to the next function should + * continue to the next function + * @return this + */ + public SchedulerOrderDefinition thenByCreatedAppId(String appId) { + return this.thenBy(t -> appId.equals(t.createdByAppId())); + } + + /** + * Adds the rest of the {@link SchedulerComponent} at this position which got + * not filtered out before. + * + * @return this + */ + public SchedulerOrderDefinition rest() { + return this.thenBy(t -> true); + } + + @Override + public int compare(SchedulerComponent o1, SchedulerComponent o2) { + final var index1 = this.indexOfMatch(o1); + final var index2 = this.indexOfMatch(o2); + + for (int i = 0; i < Math.max(index1.length, index2.length); i++) { + if (i >= index1.length) { + return 1; + } + if (i >= index2.length) { + return -1; + } + final var i1Value = index1[i]; + final var i2Value = index2[i]; + if (i1Value < i2Value) { + return -1; + } + if (i1Value > i2Value) { + return 1; + } + } + return 0; + } + + /** + * Checks if the given {@link SchedulerComponent} is handled by this + * {@link SchedulerOrderDefinition}. + * + * @param o the {@link SchedulerComponent} + * @return true if the {@link SchedulerComponent} is handled by this order + */ + public boolean contains(SchedulerComponent o) { + return this.indexOfMatch(o).length != 0; + } + + private final int[] indexOfMatch(SchedulerComponent o) { + final var iterator = this.predicates.listIterator(); + while (iterator.hasNext()) { + final var index = iterator.nextIndex(); + final var predicate = iterator.next(); + final var result = predicate.apply(o); + + if (result instanceof PositionReturnType.Next) { + continue; + } + if (result instanceof PositionReturnType.Remove) { + return EMPTY_INT_ARRAY; + } + if (result instanceof PositionReturnType.Right right) { + final var array = new int[right.index.length + 1]; + array[0] = index; + System.arraycopy(right.index, 0, array, 1, right.index.length); + return array; + } + } + return EMPTY_INT_ARRAY; + } + + } + + @Override + public void reset() { + this.schedulerComponents = new LinkedList<>(); + this.removeSchedulerComponents = new LinkedList<>(); + } + + @Override + public void aggregate(// + final SchedulerByCentralOrderConfiguration currentConfiguration, // + final SchedulerByCentralOrderConfiguration lastConfiguration // + ) { + if (currentConfiguration != null) { + this.schedulerComponents.addAll(currentConfiguration.componentOrder()); + } + if (lastConfiguration != null) { + var schedulerIdDiff = new ArrayList<>(lastConfiguration.componentOrder()); + if (currentConfiguration != null) { + schedulerIdDiff.removeAll(currentConfiguration.componentOrder()); + } + this.removeSchedulerComponents.addAll(schedulerIdDiff); + } + } + + @Override + public void create(User user, List otherAppConfigurations) throws OpenemsNamedException { + if (!this.anyCreateChanges()) { + this.delete(user, otherAppConfigurations); + return; + } + + final var handledIds = new TreeSet<>(this.order); + for (final var component : this.schedulerComponents) { + if (!this.order.contains(component)) { + throw new OpenemsException("Unhandled component " + component); + } + handledIds.add(component); + } + + for (final var config : otherAppConfigurations) { + final var schedulerConfig = config.getConfiguration(SchedulerByCentralOrderAggregateTask.class); + if (schedulerConfig == null) { + continue; + } + + for (final var component : schedulerConfig.componentOrder()) { + if (!this.order.contains(component)) { + throw new OpenemsException("Unhandled component " + component); + } + handledIds.add(component); + } + } + + final var existingIds = this.componentUtil.removeIdsWhichNotExist( + handledIds.stream().map(SchedulerComponent::id).toList(), this.aggregateTask.getCreatedComponents()); + handledIds.removeIf(t -> !existingIds.contains(t.id())); + + final var schedulerIds = this.componentUtil.getSchedulerIds(); + for (final var id : schedulerIds) { + final var existingComponent = handledIds.stream() // + .filter(t -> t.id().equals(id)) // + .findAny() // + .orElse(null); + if (existingComponent != null) { + continue; + } + + // also include existing components based on their factory id + try { + final var component = this.componentManager.getComponent(id); + final var schedulerComponent = new SchedulerComponent(id, component.serviceFactoryPid(), null); + if (!this.order.contains(schedulerComponent)) { + continue; + } + if (!handledIds.contains(schedulerComponent)) { + handledIds.add(schedulerComponent); + } + } catch (OpenemsNamedException e) { + // configured id in scheduler does not exist + } + } + + final var finalOrder = new ArrayList<>(schedulerIds); + for (final var schedulerComponent : handledIds) { + final var lower = handledIds.lower(schedulerComponent); + final var higher = handledIds.higher(schedulerComponent); + final var iLower = lower == null ? -1 : finalOrder.indexOf(lower.id()); + final var i = finalOrder.indexOf(schedulerComponent.id()); + final var iHigher = higher == null ? -1 : finalOrder.indexOf(higher.id()); + + if (i != -1 // + && (iLower == -1 || iLower < i) // + && (iHigher == -1 || iHigher > i)) { + // already correctly inserted + continue; + } + + final var insertIndex = Math.max(iLower + 1, iHigher); + finalOrder.add(insertIndex, schedulerComponent.id()); + if (i != -1) { + finalOrder.remove(Math.max(0, insertIndex >= i ? i : (i - 1))); + } + } + + final var idsToRemove = this.getIdsToRemove(otherAppConfigurations); + finalOrder.removeAll(idsToRemove); + + this.componentUtil.setSchedulerComponentIds(user, finalOrder); + } + + @Override + public void delete(User user, List otherAppConfigurations) throws OpenemsNamedException { + if (!this.anyDeleteChanges()) { + return; + } + + this.componentUtil.removeIdsInSchedulerIfExisting(user, this.getIdsToRemove(otherAppConfigurations)); + } + + private List getIdsToRemove(List otherAppConfigurations) { + final var otherIds = AppConfiguration + .flatMap(otherAppConfigurations, SchedulerByCentralOrderAggregateTask.class, + SchedulerByCentralOrderConfiguration::componentOrder) // + .toList(); + + this.removeSchedulerComponents.removeIf(t -> otherIds.stream().anyMatch(c -> c.id().equals(t.id()))); + final var idsToRemove = new ArrayList<>( + this.removeSchedulerComponents.stream().map(SchedulerComponent::id).toList()); + idsToRemove.addAll(this.aggregateTask.getDeletedComponents()); + + return idsToRemove; + } + + @Override + public String getGeneralFailMessage(Language l) { + final var bundle = AppManagerAppHelperImpl.getTranslationBundle(l); + return TranslationUtil.getTranslation(bundle, "canNotUpdateScheduler"); + } + + @Override + public AggregateTaskExecuteConstraints getExecuteConstraints() { + return new AggregateTaskExecuteConstraints(Set.of(// + // Needs to run after the AggregateTask.ComponentAggregateTask to also remove + // ids in the scheduler of components which got deleted + ComponentAggregateTask.class // + )); + } + + @Override + public void validate(// + final List errors, // + final AppConfiguration appConfiguration, // + final SchedulerByCentralOrderConfiguration configuration // + ) { + if (configuration.componentOrder().isEmpty()) { + return; + } + + List existingOrder; + try { + existingOrder = this.componentUtil.getSchedulerIds(); + } catch (OpenemsNamedException e) { + errors.add(e.getMessage()); + return; + } + + final var expectedOrder = new TreeSet<>(this.order); + for (final var componentId : existingOrder) { + final var instances = this.getAppsWithSchedulerComponent(componentId); + + if (instances.size() != 1) { + // not created with app + continue; + } + final var entry = instances.entrySet().iterator().next(); + final var appId = entry.getKey().appId; + final var schedulerComponents = entry.getValue(); + if (schedulerComponents.isEmpty()) { + continue; + } + if (schedulerComponents.size() > 1) { + errors.add("Multiple SchedulerComponents found with the same id"); + continue; + } + final var schedulerComponent = schedulerComponents.get(0); + expectedOrder.add(new SchedulerComponent(componentId, schedulerComponent.factoryId(), appId)); + } + + for (final var schedulerComponent : configuration.componentOrder()) { + final var higher = expectedOrder.higher(schedulerComponent); + final var lower = expectedOrder.lower(schedulerComponent); + if (!expectedOrder.add(schedulerComponent)) { + // check if id was configured between the expected ids + final var highIndex = higher == null ? -1 : existingOrder.indexOf(higher.id()); + final var index = existingOrder.indexOf(schedulerComponent.id()); + final var lowIndex = lower == null ? -1 : existingOrder.indexOf(lower.id()); + + if ((highIndex == -1 || highIndex > index) // + && (lowIndex != -1 || lowIndex < index)) { + continue; + } + } + + errors.add("Expected '" // + + schedulerComponent.id() // + + "' to be configured between '" // + + (lower == null ? "TOP" : lower.id()) // + + "' and '" // + + (higher == null ? "BOTTOM" : higher.id()) // + + "'"); + } + } + + private boolean anyCreateChanges() { + return !this.schedulerComponents.isEmpty(); + } + + private boolean anyDeleteChanges() { + return !this.removeSchedulerComponents.isEmpty(); + } + + private Map> getAppsWithSchedulerComponent(String componentId) { + return this.appManagerUtil.getInstantiatedApps().stream() // + .>mapMulti((t, c) -> { + try { + final var configuration = this.appManagerUtil.getAppConfiguration(ConfigurationTarget.VALIDATE, + t, Language.DEFAULT); + + final var schedulerConfig = configuration + .getConfiguration(SchedulerByCentralOrderAggregateTask.class); + if (schedulerConfig == null) { + return; + } + for (var schedulerComponent : schedulerConfig.componentOrder()) { + if (schedulerComponent.id().equals(componentId)) { + c.accept(Map.entry(t, schedulerComponent)); + } + } + } catch (OpenemsNamedException e) { + // can not get app configuration + } + }) // + .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toList()))); + } + +} diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderConfiguration.java b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderConfiguration.java new file mode 100644 index 00000000000..bfa3825e23a --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderConfiguration.java @@ -0,0 +1,20 @@ +package io.openems.edge.core.appmanager.dependency.aggregatetask; + +import java.util.List; +import java.util.stream.Stream; + +public record SchedulerByCentralOrderConfiguration(List componentOrder) { + + public static record SchedulerComponent(// + String id, // + String factoryId, // + String createdByAppId // nullable + ) { + + } + + public SchedulerByCentralOrderConfiguration(SchedulerComponent... components) { + this(Stream.of(components).toList()); + } + +} diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_de.properties b/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_de.properties index 97b7726bcb4..4781fdc8dc7 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_de.properties +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_de.properties @@ -190,6 +190,10 @@ App.IntegratedSystem.feedInType.dynamicLimitation = Dynamische Einspeisung App.IntegratedSystem.feedInType.externalLimitation = Externe Limitierung App.IntegratedSystem.feedInType.noLimitation = Keine Limitierung App.IntegratedSystem.feedInType.label = Einspeisetyp +App.IntegratedSystem.gridMeterType.label = Installierter Netzzähler +App.IntegratedSystem.gridMeterType.option.smartMeter = Home 3-Phasensensor mit Stromwandler 120 A (Standardlieferumfang) +App.IntegratedSystem.gridMeterType.option.commercialMeter = Home 3-Phasensensor ohne Stromwandler (Optional) +App.IntegratedSystem.ctRatioFirst.label = Wandler-Primärstrom (200A - 5000A/5A) App.IntegratedSystem.shadowManagementDisabled.label = Schattenmanagement deaktivieren App.IntegratedSystem.shadowManagementDisabled.description = Nur wenn Optimierer verbaut sind, muss das Schattenmanagement deaktiviert werden @@ -197,6 +201,7 @@ App.IntegratedSystem.modbus0.alias = Kommunikation mit der Batterie App.IntegratedSystem.modbus0N.alias = Kommunikation mit den Batterien App.IntegratedSystem.modbus1.alias = Kommunikation mit dem Batterie-Wechselrichter App.IntegratedSystem.modbus1N.alias = Kommunikation mit dem Batterie-Wechselrichter {0} +App.IntegratedSystem.modbus2.alias = externe RS485 Schnittstelle App.IntegratedSystem.io0.alias = EMS Box Relais App.IntegratedSystem.battery0.alias = Batterie App.IntegratedSystem.batteryN.alias = Batterie {0} @@ -308,6 +313,8 @@ App.PeakShaving.PhaseAccuratePeakShaving.Name.short = Phasengenaue Lastspitzenka App.PvInverter.ip.description = IP-Adresse des PV-Wechselrichters. App.PvInverter.port.description = Port des PV-Wechselrichters. App.PvInverter.modbusUnitId.description = Modbus Unit-ID des PV-Wechselrichters. +App.PvInverter.phase.label = Phasen +App.PvInverter.phase.description = Angeschlossene Phase(n) des Wechselrichters App.PvInverter.Fronius.Name = Fronius PV-Wechselrichter App.PvInverter.Fronius.Name.short = Fronius @@ -318,8 +325,6 @@ App.PvInverter.Kostal.Name.short = KOSTAL App.PvInverter.Sma.Name = SMA PV-Wechselrichter App.PvInverter.Sma.Name.short = SMA App.PvInverter.Sma.modbusUnitId.description = Modbus Unit-ID des PV-Wechselrichters. Beachten Sie, dass Sie laut Handbuch zu dem Wert, den Sie in der SMA Webschnittstelle konfiguriert haben, den Wert '123' addieren müssen. -App.PvInverter.Sma.phase.label = Phasen -App.PvInverter.Sma.phase.description = Angeschlossene Phase(n) des Wechselrichters App.PvInverter.SolarEdge.Name = SolarEdge PV-Wechselrichter App.PvInverter.SolarEdge.Name.short = SolarEdge @@ -349,7 +354,7 @@ App.TimeOfUseTariff.Stromdao.zipCode.description = Deutsche Postleitzahl des Woh App.TimeOfUseTariff.Tibber.Name = Dynamischer Stromtarif (Tibber) App.TimeOfUseTariff.Tibber.Name.short = Tibber App.TimeOfUseTariff.Tibber.accessToken.label = Token -App.TimeOfUseTariff.Tibber.accessToken.description = Personal Access Token von Tibber +App.TimeOfUseTariff.Tibber.accessToken.description = Für die Verknüpfung mit ihrem Tibber-Account benötigen Sie einen persönlichen Access-Token. Diesen können Sie unter "developer.tibber.com/settings/access-token" erstellen. App.TimeOfUseTariff.Tibber.filterForHome.label = Filter für Home App.TimeOfUseTariff.Tibber.filterForHome.description = Bei mehreren 'Homes', entweder ID (Format UUID) oder 'appNickname' für eindeutige indentifizierung eintragen @@ -374,5 +379,8 @@ App.Ess.PrepareBatteryExtension.Name = Batterienachrüstung App.Ess.PrepareBatteryExtension.Name.short = Batterienachrüstung App.Ess.PrepareBatteryExtension.targetSoc.label = Ziel Soc +App.Ess.PowerPlantController.Name = Erzeugungsanlagen-Regler +App.Ess.PowerPlantController.Name.short = EZA-Regler + App.Ess.FixActivePower.Name = Manuelle Be-/Entladung App.Ess.FixActivePower.Name.short = Manuelle Be-/Entladung diff --git a/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_en.properties b/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_en.properties index 656a0da0635..1b440f43fe9 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_en.properties +++ b/io.openems.edge.core/src/io/openems/edge/core/appmanager/translation_en.properties @@ -190,6 +190,10 @@ App.IntegratedSystem.feedInType.dynamicLimitation = dynamic limitation App.IntegratedSystem.feedInType.externalLimitation = external limitation App.IntegratedSystem.feedInType.noLimitation = no limitation App.IntegratedSystem.feedInType.label = Feed in type +App.IntegratedSystem.gridMeterType.label = Installed Grid-Meter +App.IntegratedSystem.gridMeterType.option.smartMeter = Home 3-phase sensor with 120 A current transformer (standard scope of delivery) +App.IntegratedSystem.gridMeterType.option.commercialMeter = Home 3-phase sensor without current transformer (optional) +App.IntegratedSystem.ctRatioFirst.label = CT-Ratio (200A - 5000A/5A) App.IntegratedSystem.shadowManagementDisabled.label = Deactivate shadow management App.IntegratedSystem.shadowManagementDisabled.description = Only if optimisers are installed, shadow management must be deactivated @@ -197,6 +201,7 @@ App.IntegratedSystem.modbus0.alias = Communication with the battery App.IntegratedSystem.modbus0N.alias = Communication with the batteries App.IntegratedSystem.modbus1.alias = Communication with the battery inverter App.IntegratedSystem.modbus1N.alias = Communication with the battery inverter {0} +App.IntegratedSystem.modbus2.alias = external RS485 interface App.IntegratedSystem.io0.alias = EMS Box Relay App.IntegratedSystem.battery0.alias = battery App.IntegratedSystem.batteryN.alias = battery {0} @@ -307,7 +312,8 @@ App.PeakShaving.PhaseAccuratePeakShaving.Name.short = Phase accurate peak shavin # PV inverter App.PvInverter.ip.description = IP address of the PV inverter. App.PvInverter.port.description = Port of the PV inverter. -App.PvInverter.modbusUnitId.description = Modbus Unit-ID of the PV inverter. +App.PvInverter.phase.label = Phase +App.PvInverter.phase.description = Connected phase(s) of the inverter App.PvInverter.Fronius.Name = Fronius PV inverter App.PvInverter.Fronius.Name.short = Fronius @@ -318,8 +324,6 @@ App.PvInverter.Kostal.Name.short = KOSTAL App.PvInverter.Sma.Name = SMA PV inverter App.PvInverter.Sma.Name.short = SMA App.PvInverter.Sma.modbusUnitId.description = The Unit-ID of the Modbus device. Be aware, that according to the manual you need to add '123' to the value that you configured in the SMA web interface. -App.PvInverter.Sma.phase.label = Phase -App.PvInverter.Sma.phase.description = Connected phase(s) of the inverter App.PvInverter.SolarEdge.Name = SolarEdge PV inverter App.PvInverter.SolarEdge.Name.short = SolarEdge @@ -349,7 +353,7 @@ App.TimeOfUseTariff.Stromdao.zipCode.description = German postal code of place o App.TimeOfUseTariff.Tibber.Name = Time-of-Use Tariff (Tibber) App.TimeOfUseTariff.Tibber.Name.short = Tibber App.TimeOfUseTariff.Tibber.accessToken.label = Token -App.TimeOfUseTariff.Tibber.accessToken.description = Personal access token from Tibber +App.TimeOfUseTariff.Tibber.accessToken.description = To link to your Tibber account you need a personal access token. You can create this under "developer.tibber.com/settings/access-token". App.TimeOfUseTariff.Tibber.filterForHome.label = Filter for Home App.TimeOfUseTariff.Tibber.filterForHome.description = For multiple 'Homes', add either an ID (format UUID) or 'appNickname' for unambiguous identification @@ -374,5 +378,8 @@ App.Ess.PrepareBatteryExtension.Name = Prepare Battery Extension App.Ess.PrepareBatteryExtension.Name.short = Prepare Battery Extension App.Ess.PrepareBatteryExtension.targetSoc.label = Target Soc +App.Ess.PowerPlantController.Name = Power Plant Controller +App.Ess.PowerPlantController.Name.short = PPC + App.Ess.FixActivePower.Name = Manual Charge/Discharge App.Ess.FixActivePower.Name.short = Manual Charge/Discharge diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/HostImpl.java b/io.openems.edge.core/src/io/openems/edge/core/host/HostImpl.java index 7ee3e3532c9..fa89606796f 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/HostImpl.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/HostImpl.java @@ -31,6 +31,7 @@ import io.openems.edge.common.jsonapi.JsonApi; import io.openems.edge.common.user.User; import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandRequest; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemRestartRequest; import io.openems.edge.core.host.jsonrpc.ExecuteSystemUpdateRequest; import io.openems.edge.core.host.jsonrpc.GetNetworkConfigRequest; import io.openems.edge.core.host.jsonrpc.GetNetworkConfigResponse; @@ -54,7 +55,6 @@ public class HostImpl extends AbstractOpenemsComponent implements Host, OpenemsC private final DiskSpaceWorker diskSpaceWorker; private final NetworkConfigurationWorker networkConfigurationWorker; private final UsbConfigurationWorker usbConfigurationWorker; - private final SystemUpdateHandler systemUpdateHandler; @Reference @@ -143,7 +143,6 @@ protected void deactivate() { public CompletableFuture handleJsonrpcRequest(User user, JsonrpcRequest request) throws OpenemsNamedException { user.assertRoleIsAtLeast("handleJsonrpcRequest", Role.OWNER); - switch (request.getMethod()) { case GetNetworkConfigRequest.METHOD: @@ -161,6 +160,9 @@ public CompletableFuture handleJsonrpcRequest( case ExecuteSystemCommandRequest.METHOD: return this.handleExecuteCommandRequest(user, ExecuteSystemCommandRequest.from(request)); + case ExecuteSystemRestartRequest.METHOD: + return this.handleExecuteSystemRestartRequest(user, ExecuteSystemRestartRequest.from(request)); + default: throw OpenemsError.JSONRPC_UNHANDLED_METHOD.exception(request.getMethod()); } @@ -243,7 +245,21 @@ private CompletableFuture handleExecuteSystemUpdateReque private CompletableFuture handleExecuteCommandRequest(User user, ExecuteSystemCommandRequest request) throws OpenemsNamedException { user.assertRoleIsAtLeast("handleExecuteCommandRequest", Role.ADMIN); - return this.operatingSystem.handleExecuteCommandRequest(request); + return this.operatingSystem.handleExecuteSystemCommandRequest(request); + } + + /** + * Handles a {@link ExecuteSystemRestartRequest}. + * + * @param user the User + * @param request the {@link ExecuteSystemRestartRequest} + * @return the Future JSON-RPC Response + * @throws OpenemsNamedException on error + */ + private CompletableFuture handleExecuteSystemRestartRequest(User user, + ExecuteSystemRestartRequest request) throws OpenemsNamedException { + user.assertRoleIsAtLeast("handleExecuteSystemRestartRequest", Role.OWNER); + return this.operatingSystem.handleExecuteSystemRestartRequest(request); } @Override diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystem.java b/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystem.java index b4d491d69b8..ef8c3cacbb3 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystem.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystem.java @@ -2,10 +2,14 @@ import java.util.concurrent.CompletableFuture; +import io.openems.common.exceptions.NotImplementedException; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.jsonrpc.base.JsonrpcResponseSuccess; import io.openems.edge.common.user.User; import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandRequest; import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandResponse; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemRestartRequest; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemRestartResponse; import io.openems.edge.core.host.jsonrpc.SetNetworkConfigRequest; public interface OperatingSystem { @@ -40,11 +44,21 @@ public void handleSetNetworkConfigRequest(User user, NetworkConfiguration oldNet /** * Executes a command. * - * @param request the ExecuteCommandRequest - * @return a ExecuteCommandResponse + * @param request the {@link ExecuteSystemCommandRequest} + * @return a {@link ExecuteSystemCommandResponse} * @throws OpenemsNamedException on error */ - public CompletableFuture handleExecuteCommandRequest( + public CompletableFuture handleExecuteSystemCommandRequest( ExecuteSystemCommandRequest request) throws OpenemsNamedException; + /** + * Executes a system restart (soft or hard). + * + * @param request the {@link ExecuteSystemRestartRequest} + * @return an {@link ExecuteSystemRestartResponse} + * @throws OpenemsNamedException on error + */ + public CompletableFuture handleExecuteSystemRestartRequest( + ExecuteSystemRestartRequest request) throws NotImplementedException; + } diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemDebianSystemd.java b/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemDebianSystemd.java index 9edb9e6d887..5b0765051d2 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemDebianSystemd.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemDebianSystemd.java @@ -1,5 +1,9 @@ package io.openems.edge.core.host; +import static java.lang.Runtime.getRuntime; +import static java.util.concurrent.CompletableFuture.runAsync; +import static java.util.concurrent.CompletableFuture.supplyAsync; + import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -16,11 +20,13 @@ import java.util.HashSet; import java.util.List; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; import java.util.function.Supplier; import java.util.regex.Pattern; @@ -36,7 +42,11 @@ import io.openems.edge.common.type.TypeUtils; import io.openems.edge.common.user.User; import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandRequest; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandRequest.SystemCommand; import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandResponse; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandResponse.SystemCommandResponse; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemRestartRequest; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemRestartResponse; import io.openems.edge.core.host.jsonrpc.SetNetworkConfigRequest; /** @@ -137,7 +147,7 @@ public void handleSetNetworkConfigRequest(User user, NetworkConfiguration oldNet } // apply the configuration by restarting the systemd-networkd service - this.handleExecuteCommandRequest(ExecuteSystemCommandRequest + this.handleExecuteSystemCommandRequest(ExecuteSystemCommandRequest .runInBackgroundWithoutAuthentication("systemctl restart systemd-networkd --no-block")); } @@ -219,78 +229,99 @@ private List toFileFormat(User user, NetworkInterface iface) throws O } @Override - public CompletableFuture handleExecuteCommandRequest( + public CompletableFuture handleExecuteSystemCommandRequest( ExecuteSystemCommandRequest request) { var result = new CompletableFuture(); + this.execute(request.systemCommand, // + scr -> result.complete(new ExecuteSystemCommandResponse(request.id, scr)), + e -> result.completeExceptionally(e)); + return result; + } + @Override + public CompletableFuture handleExecuteSystemRestartRequest( + ExecuteSystemRestartRequest request) { + final var result = new CompletableFuture(); + var sc = new SystemCommand(// + switch (request.type) { // actual command string + case HARD -> "/usr/bin/systemctl reboot -i"; // "-i" is for "ignore inhibitors and users" + case SOFT -> "/usr/bin/systemctl restart openems"; + }, // + false, // runInBackground + 5, // timeoutSeconds + Optional.empty(), // username + Optional.empty()); // password + this.execute(sc, // + scr -> result.complete(new ExecuteSystemRestartResponse(request.id, scr)), + e -> result.completeExceptionally(e)); + return result; + } + + private void execute(SystemCommand sc, Consumer scr, Consumer error) { try { - Process proc; - if (request.getUsername().isPresent() && request.getPassword().isPresent()) { + final Process proc; + if (sc.username().isPresent() && sc.password().isPresent()) { // Authenticate with user and password - proc = Runtime.getRuntime().exec(new String[] { // + proc = getRuntime().exec(new String[] { // "/bin/bash", "-c", "--", // - "echo " + request.getPassword().get() + " | " // - + " /usr/bin/sudo -Sk -p '' -u \"" + request.getUsername().get() + "\" -- " // - + request.getCommand() }); - } else if (request.getPassword().isPresent()) { + "echo " + sc.password().get() + " | " // + + " /usr/bin/sudo -Sk -p '' -u \"" + sc.username().get() + "\" -- " // + + sc.command() }); + } else if (sc.password().isPresent()) { // Authenticate with password (user must have 'sudo' permissions) - proc = Runtime.getRuntime().exec(new String[] { // + proc = getRuntime().exec(new String[] { // "/bin/bash", "-c", "--", // - "echo " + request.getPassword().get() + " | " // + "echo " + sc.password().get() + " | " // + " /usr/bin/sudo -Sk -p '' -- " // - + request.getCommand() }); + + sc.command() }); } else { // No authentication: run as current user - proc = Runtime.getRuntime().exec(new String[] { // - "/bin/bash", "-c", "--", request.getCommand() }); + proc = getRuntime().exec(new String[] { // + "/bin/bash", "-c", "--", sc.command() }); } // get stdout and stderr - CompletableFuture> stdoutFuture = CompletableFuture - .supplyAsync(new InputStreamToString(this.parent, request.getCommand(), proc.getInputStream())); - CompletableFuture> stderrFuture = CompletableFuture - .supplyAsync(new InputStreamToString(this.parent, request.getCommand(), proc.getErrorStream())); + var stdoutFuture = supplyAsync(new InputStreamToString(this.parent, sc.command(), proc.getInputStream())); + var stderrFuture = supplyAsync(new InputStreamToString(this.parent, sc.command(), proc.getErrorStream())); - if (request.isRunInBackground()) { + if (sc.runInBackground()) { /* * run in background */ - String[] stdout = { // - "Command [" + request.getCommand() + "] executed in background...", // + var stdout = new String[] { // + "Command [" + sc.command() + "] executed in background...", // "Check system logs for more information." }; - result.complete(new ExecuteSystemCommandResponse(request.getId(), stdout, new String[0], 0)); + scr.accept(new SystemCommandResponse(stdout, new String[0], 0)); } else { /* * run in foreground with timeout */ - CompletableFuture.runAsync(() -> { - List stderr = new ArrayList<>(); + runAsync(() -> { + var stderr = new ArrayList<>(); try { // apply command timeout - if (!proc.waitFor(request.getTimeoutSeconds(), TimeUnit.SECONDS)) { - stderr.add("Command [" + request.getCommand() + "] timed out."); + if (!proc.waitFor(sc.timeoutSeconds(), TimeUnit.SECONDS)) { + stderr.add("Command [" + sc.command() + "] timed out."); proc.destroy(); } var stdout = stdoutFuture.get(1, TimeUnit.SECONDS); stderr.addAll(stderrFuture.get(1, TimeUnit.SECONDS)); - result.complete(new ExecuteSystemCommandResponse(request.getId(), // + scr.accept(new SystemCommandResponse(// stdout.toArray(new String[stdout.size()]), // stderr.toArray(new String[stderr.size()]), // proc.exitValue() // )); } catch (Throwable e) { - result.completeExceptionally(e); + error.accept(e); } }); } } catch (IOException e) { - result.completeExceptionally(e); + error.accept(e); } - - return result; } /** diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemWindows.java b/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemWindows.java index 56a29127eae..68c509a86a4 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemWindows.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/OperatingSystemWindows.java @@ -5,9 +5,11 @@ import io.openems.common.exceptions.NotImplementedException; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.jsonrpc.base.JsonrpcResponseSuccess; import io.openems.edge.common.user.User; import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandRequest; import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandResponse; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemRestartRequest; import io.openems.edge.core.host.jsonrpc.SetNetworkConfigRequest; /** @@ -31,7 +33,7 @@ public void handleSetNetworkConfigRequest(User user, NetworkConfiguration oldNet } @Override - public CompletableFuture handleExecuteCommandRequest( + public CompletableFuture handleExecuteSystemCommandRequest( ExecuteSystemCommandRequest request) throws NotImplementedException { throw new NotImplementedException("ExecuteSystemCommandRequest is not implemented for Windows"); } @@ -42,4 +44,10 @@ public String getUsbConfiguration() throws OpenemsNamedException { return ""; } + @Override + public CompletableFuture handleExecuteSystemRestartRequest( + ExecuteSystemRestartRequest request) throws NotImplementedException { + throw new NotImplementedException("ExecuteSystemRestartRequest is not implemented for Windows"); + } + } diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/SystemUpdateHandler.java b/io.openems.edge.core/src/io/openems/edge/core/host/SystemUpdateHandler.java index efcf06fe7fd..085d2b33c95 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/SystemUpdateHandler.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/SystemUpdateHandler.java @@ -78,7 +78,7 @@ protected CompletableFuture handleGetSystemUpdateStateRe result.completeExceptionally(ex); return; } - var stdout = response.getStdout(); + var stdout = response.scr.stdout(); if (stdout.length < 1) { result.completeExceptionally(ex /* todo */); return; @@ -119,7 +119,7 @@ private CompletableFuture executeSystemCommand(Str final var runInBackground = false; final Optional username = Optional.empty(); final Optional password = Optional.empty(); - return this.parent.operatingSystem.handleExecuteCommandRequest( + return this.parent.operatingSystem.handleExecuteSystemCommandRequest( new ExecuteSystemCommandRequest(command, runInBackground, timeoutSeconds, username, password)); } @@ -181,14 +181,14 @@ private void executeUpdate(CompletableFuture result) thr final float totalNumberOfLines = script.split("\r\n|\r|\n").length; // Make sure 'at' command is available - if (this.executeSystemCommand("which at", SHORT_TIMEOUT).get().getStdout().length == 0) { + if (this.executeSystemCommand("which at", SHORT_TIMEOUT).get().scr.stdout().length == 0) { this.updateState.addLog("# Command 'at' is missing"); { this.updateState.addLog("# Executing 'apt-get update'"); var response = this.executeSystemCommand("apt-get update", 3600).get(); this.updateState.addLog("'apt-get update'", response); - if (response.getExitCode() != 0) { + if (response.scr.exitcode() != 0) { throw new Exception("'apt-get update' failed"); } } @@ -196,7 +196,7 @@ private void executeUpdate(CompletableFuture result) thr this.updateState.addLog("# Executing 'apt-get install at'"); var response = this.executeSystemCommand("apt-get -y install at", 3600).get(); this.updateState.addLog("'apt-get install at'", response); - if (response.getExitCode() != 0) { + if (response.scr.exitcode() != 0) { throw new Exception("'apt-get install at' failed"); } } @@ -215,7 +215,7 @@ private void executeUpdate(CompletableFuture result) thr + " fi; " // + " } >" + logFile.toAbsolutePath() + " 2>&1' " // + "| at now", SHORT_TIMEOUT).get(); - if (response.getExitCode() != 0) { + if (response.scr.exitcode() != 0) { throw new Exception("Executing update script [" + scriptFile + "] failed"); } } diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandRequest.java b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandRequest.java index cd39b464af7..7e5c760386b 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandRequest.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandRequest.java @@ -33,6 +33,27 @@ public class ExecuteSystemCommandRequest extends JsonrpcRequest { public static final boolean DEFAULT_RUN_IN_BACKGROUND = false; public static final int DEFAULT_TIMEOUT_SECONDS = 5; + /** + * Holds common parameters for a {@link SystemCommand}. + */ + public static record SystemCommand(String command, boolean runInBackground, int timeoutSeconds, + Optional username, Optional password) { + + private JsonObject toJsonObject() { + var result = JsonUtils.buildJsonObject() // + .addProperty("command", this.command) // + .addProperty("runInBackground", this.runInBackground) // + .addProperty("timeoutSeconds", this.timeoutSeconds); // + if (this.username.isPresent()) { + result.addProperty("username", this.username.get()); // + } + if (this.password.isPresent()) { + result.addProperty("password", this.password.get()); // + } + return result.build(); + } + } + /** * Parses a generic {@link JsonrpcRequest} to a * {@link ExecuteSystemCommandRequest}. @@ -49,15 +70,10 @@ public static ExecuteSystemCommandRequest from(JsonrpcRequest r) throws OpenemsN int timeoutSeconds = JsonUtils.getAsOptionalInt(p, "timeoutSeconds").orElse(DEFAULT_TIMEOUT_SECONDS); var username = JsonUtils.getAsOptionalString(p, "username"); var password = JsonUtils.getAsOptionalString(p, "password"); - return new ExecuteSystemCommandRequest(r.getId(), command, runInBackground, timeoutSeconds, username, password); + return new ExecuteSystemCommandRequest(r.getId(), + new SystemCommand(command, runInBackground, timeoutSeconds, username, password)); } - private final String command; - private final boolean runInBackground; - private final int timeoutSeconds; - private final Optional username; - private final Optional password; - /** * Factory without Username + Password; run in background without timeout. * @@ -65,7 +81,8 @@ public static ExecuteSystemCommandRequest from(JsonrpcRequest r) throws OpenemsN * @return the {@link ExecuteSystemCommandRequest} */ public static ExecuteSystemCommandRequest runInBackgroundWithoutAuthentication(String command) { - return new ExecuteSystemCommandRequest(UUID.randomUUID(), command, true, 0, Optional.empty(), Optional.empty()); + return new ExecuteSystemCommandRequest(UUID.randomUUID(), + new SystemCommand(command, true, 0, Optional.empty(), Optional.empty())); } /** @@ -79,84 +96,25 @@ public static ExecuteSystemCommandRequest runInBackgroundWithoutAuthentication(S */ public static ExecuteSystemCommandRequest withoutAuthentication(String command, boolean runInBackground, int timeoutSeconds) { - return new ExecuteSystemCommandRequest(UUID.randomUUID(), command, runInBackground, timeoutSeconds, - Optional.empty(), Optional.empty()); + return new ExecuteSystemCommandRequest(UUID.randomUUID(), + new SystemCommand(command, runInBackground, timeoutSeconds, Optional.empty(), Optional.empty())); } + public final SystemCommand systemCommand; + public ExecuteSystemCommandRequest(String command, boolean runInBackground, int timeoutSeconds, Optional username, Optional password) { - this(UUID.randomUUID(), command, runInBackground, timeoutSeconds, username, password); + this(UUID.randomUUID(), new SystemCommand(command, runInBackground, timeoutSeconds, username, password)); } - public ExecuteSystemCommandRequest(UUID id, String command, boolean runInBackground, int timeoutSeconds, - Optional username, Optional password) { - super(id, METHOD, - timeoutSeconds + JsonrpcRequest.DEFAULT_TIMEOUT_SECONDS /* reuse timeoutSeconds with some buffer */); - this.command = command; - this.runInBackground = runInBackground; - this.timeoutSeconds = timeoutSeconds; - this.username = username; - this.password = password; + public ExecuteSystemCommandRequest(UUID id, SystemCommand systemCommand) { + super(id, METHOD, systemCommand.timeoutSeconds + + JsonrpcRequest.DEFAULT_TIMEOUT_SECONDS /* reuse timeoutSeconds with some buffer */); + this.systemCommand = systemCommand; } @Override public JsonObject getParams() { - var result = JsonUtils.buildJsonObject() // - .addProperty("command", this.command) // - .addProperty("runInBackground", this.runInBackground) // - .addProperty("timeoutSeconds", this.timeoutSeconds); // - if (this.username.isPresent()) { - result.addProperty("username", this.username.get()); // - } - if (this.password.isPresent()) { - result.addProperty("password", this.password.get()); // - } - return result.build(); - } - - /** - * Gets the request command. - * - * @return the command - */ - public String getCommand() { - return this.command; - } - - /** - * Gets the request isRunInBackground option. - * - * @return the isRunInBackground option - */ - public boolean isRunInBackground() { - return this.runInBackground; - } - - /** - * Gets the request timeout. - * - * @return the timeout in seconds - */ - public int getTimeoutSeconds() { - return this.timeoutSeconds; + return this.systemCommand.toJsonObject(); } - - /** - * Gets the request username. - * - * @return the username - */ - public Optional getUsername() { - return this.username; - } - - /** - * Gets the request password. - * - * @return the password - */ - public Optional getPassword() { - return this.password; - } - } diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandResponse.java b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandResponse.java index bc112a3bd5b..fc3b40b57a8 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandResponse.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemCommandResponse.java @@ -1,15 +1,17 @@ package io.openems.edge.core.host.jsonrpc; import java.util.UUID; +import java.util.stream.Stream; -import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import io.openems.common.jsonrpc.base.JsonrpcResponseSuccess; import io.openems.common.utils.JsonUtils; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandRequest.SystemCommand; /** - * JSON-RPC Response to "executeSystemCommand" Request. + * JSON-RPC Response to {@link ExecuteSystemCommandRequest}. * *

* @@ -27,44 +29,38 @@ */ public class ExecuteSystemCommandResponse extends JsonrpcResponseSuccess { - private final String[] stdout; - private final String[] stderr; - private final int exitcode; + /** + * Holds common parameters for a response to a {@link SystemCommand}. + */ + public static record SystemCommandResponse(String[] stdout, String[] stderr, int exitcode) { - public ExecuteSystemCommandResponse(UUID id, String[] stdout, String[] stderr, int exitcode) { - super(id); - this.stdout = stdout; - this.stderr = stderr; - this.exitcode = exitcode; - } - - @Override - public JsonObject getResult() { - var stdout = new JsonArray(); - for (String line : this.stdout) { - stdout.add(line); - } - var stderr = new JsonArray(); - for (String line : this.stderr) { - stderr.add(line); + /** + * Convert to {@link JsonObject}. + * + * @return a {@link JsonObject} + */ + public JsonObject toJsonObject() { + return JsonUtils.buildJsonObject() // + .add("stdout", Stream.of(this.stdout) // + .map(JsonPrimitive::new) // + .collect(JsonUtils.toJsonArray())) + .add("stderr", Stream.of(this.stderr) // + .map(JsonPrimitive::new) // + .collect(JsonUtils.toJsonArray())) + .addProperty("exitcode", this.exitcode) // + .build(); } - return JsonUtils.buildJsonObject() // - .add("stdout", stdout) // - .add("stderr", stderr) // - .addProperty("exitcode", this.exitcode) // - .build(); } - public String[] getStdout() { - return this.stdout; - } + public final SystemCommandResponse scr; - public String[] getStderr() { - return this.stderr; + public ExecuteSystemCommandResponse(UUID id, SystemCommandResponse scr) { + super(id); + this.scr = scr; } - public int getExitCode() { - return this.exitcode; + @Override + public JsonObject getResult() { + return this.scr.toJsonObject(); } - } diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartRequest.java b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartRequest.java new file mode 100644 index 00000000000..9f355fa70b8 --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartRequest.java @@ -0,0 +1,78 @@ +package io.openems.edge.core.host.jsonrpc; + +import static io.openems.common.utils.EnumUtils.toEnum; +import static io.openems.common.utils.JsonUtils.getAsString; + +import java.util.UUID; + +import com.google.gson.JsonObject; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.exceptions.OpenemsException; +import io.openems.common.jsonrpc.base.JsonrpcRequest; +import io.openems.common.utils.JsonUtils; + +/** + * Represents a JSON-RPC Request to execute a system restart. + * + *

+ * {
+ *   "jsonrpc": "2.0",
+ *   "id": "UUID",
+ *   "method": "executeSystemRestart",
+ *   "params": {
+ *   	"type": "SOFT" | "HARD"
+ *   }
+ * }
+ * 
+ */ +public class ExecuteSystemRestartRequest extends JsonrpcRequest { + + public static final String METHOD = "executeSystemRestart"; + + public enum Type { + /** + * SOFT: restart only the Java OpenEMS Edge process. + */ + SOFT, + /** + * HARD: reboot the device. + */ + HARD; + } + + /** + * Parses a generic {@link JsonrpcRequest} to a + * {@link ExecuteSystemRestartRequest}. + * + * @param r the {@link JsonrpcRequest} + * @return the {@link ExecuteSystemRestartRequest} + * @throws OpenemsNamedException on error + */ + public static ExecuteSystemRestartRequest from(JsonrpcRequest r) throws OpenemsNamedException { + var p = r.getParams(); + var type = toEnum(Type.class, getAsString(p, "type")); + if (type == null) { + throw new OpenemsException("Unknown type for " + p.toString()); + } + return new ExecuteSystemRestartRequest(r.getId(), type); + } + + public final Type type; + + public ExecuteSystemRestartRequest(Type type) { + this(UUID.randomUUID(), type); + } + + public ExecuteSystemRestartRequest(UUID id, Type type) { + super(id, METHOD, JsonrpcRequest.DEFAULT_TIMEOUT_SECONDS); + this.type = type; + } + + @Override + public JsonObject getParams() { + return JsonUtils.buildJsonObject() // + .addProperty("type", this.type.name()) // + .build(); + } +} diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartResponse.java b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartResponse.java new file mode 100644 index 00000000000..6bc3b532cfa --- /dev/null +++ b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/ExecuteSystemRestartResponse.java @@ -0,0 +1,41 @@ +package io.openems.edge.core.host.jsonrpc; + +import java.util.UUID; + +import com.google.gson.JsonObject; + +import io.openems.common.jsonrpc.base.JsonrpcResponseSuccess; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemCommandResponse.SystemCommandResponse; + +/** + * JSON-RPC Response to {@link ExecuteSystemRestartRequest}. + * + *

+ * + *

+ * {
+ *   "jsonrpc": "2.0",
+ *   "id": "UUID",
+ *   "result": {
+ *     "stdout": string[],
+ *     "stderr": string[],
+ *     "exitcode": number (exit code of application: 0 = successful; otherwise error)
+ *   }
+ * }
+ * 
+ */ +public class ExecuteSystemRestartResponse extends JsonrpcResponseSuccess { + + public final SystemCommandResponse scr; + + public ExecuteSystemRestartResponse(UUID id, SystemCommandResponse scr) { + super(id); + this.scr = scr; + } + + @Override + public JsonObject getResult() { + return this.scr.toJsonObject(); + } + +} diff --git a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/GetSystemUpdateStateResponse.java b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/GetSystemUpdateStateResponse.java index e5db265bab7..38ea2900958 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/GetSystemUpdateStateResponse.java +++ b/io.openems.edge.core/src/io/openems/edge/core/host/jsonrpc/GetSystemUpdateStateResponse.java @@ -19,7 +19,7 @@ import io.openems.edge.core.host.SystemUpdateHandler; /** - * JSON-RPC Response to "getSystemUpdateState" Request. + * JSON-RPC Response to {@link GetSystemUpdateStateRequest}. * *

* @@ -166,24 +166,24 @@ public void addLog(Exception e) { */ public void addLog(String label, ExecuteSystemCommandResponse response) { synchronized (this.log) { - var stdout = response.getStdout(); + var stdout = response.scr.stdout(); if (stdout.length > 0) { this.addLog(label + ": STDOUT"); - for (String line : stdout) { + for (var line : stdout) { this.addLog(label + ": " + line); } } - var stderr = response.getStderr(); + var stderr = response.scr.stderr(); if (stderr.length > 0) { this.addLog(label + ": STDERR"); - for (String line : stderr) { + for (var line : stderr) { this.addLog(label + ": " + line); } } - if (response.getExitCode() == 0) { + if (response.scr.exitcode() == 0) { this.addLog(label + ": FINISHED SUCCESSFULLY"); } else { - this.addLog(label + ": FINISHED WITH ERROR CODE [" + response.getExitCode() + "]"); + this.addLog(label + ": FINISHED WITH ERROR CODE [" + response.scr.exitcode() + "]"); } } } diff --git a/io.openems.edge.core/src/io/openems/edge/core/sum/Config.java b/io.openems.edge.core/src/io/openems/edge/core/sum/Config.java index d9983ce273b..165747eb397 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/sum/Config.java +++ b/io.openems.edge.core/src/io/openems/edge/core/sum/Config.java @@ -17,6 +17,12 @@ @AttributeDefinition(name = "Maximum ever Production power [W]", description = "Includes AC- and DC-side production. Range: positive or zero") int productionMaxActivePower() default 0; + @AttributeDefinition(name = "Maximum ever ESS Charge power [W]", description = "Range: negative or zero") + int essMinDischargePower() default 0; + + @AttributeDefinition(name = "Maximum ever ESS Discharge power [W]", description = "Range: positive or zero") + int essMaxDischargePower() default 0; + @AttributeDefinition(name = "Maximum ever Consumption power [W]", description = "Range: positive or zero") int consumptionMaxActivePower() default 0; diff --git a/io.openems.edge.core/src/io/openems/edge/core/sum/ExtremeEverValues.java b/io.openems.edge.core/src/io/openems/edge/core/sum/ExtremeEverValues.java index c9e10666cef..b230934d0ba 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/sum/ExtremeEverValues.java +++ b/io.openems.edge.core/src/io/openems/edge/core/sum/ExtremeEverValues.java @@ -2,6 +2,7 @@ import static io.openems.common.OpenemsConstants.PROPERTY_LAST_CHANGE_AT; import static io.openems.common.OpenemsConstants.PROPERTY_LAST_CHANGE_BY; +import static io.openems.edge.common.type.TypeUtils.getAsType; import java.io.IOException; import java.time.Clock; @@ -18,6 +19,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.openems.common.types.OpenemsType; import io.openems.edge.common.channel.ChannelId; import io.openems.edge.common.channel.IntegerReadChannel; import io.openems.edge.common.component.OpenemsComponent; @@ -176,7 +178,14 @@ private ExtremeEverValue(ChannelId targetChannelId, String configProperty, Range } private synchronized void initializeFromContext(ComponentContext context) { - this.configValue = this.actualValue = (int) context.getProperties().get(this.configProperty); + int value; + try { + value = getAsType(OpenemsType.INTEGER, context.getProperties().get(this.configProperty)); + } catch (Exception e) { + value = 0; + e.printStackTrace(); + } + this.configValue = this.actualValue = (int) value; } private synchronized void updateFromChannel(OpenemsComponent component) { diff --git a/io.openems.edge.core/src/io/openems/edge/core/sum/SumImpl.java b/io.openems.edge.core/src/io/openems/edge/core/sum/SumImpl.java index 3daa9571e3a..4901c486e17 100644 --- a/io.openems.edge.core/src/io/openems/edge/core/sum/SumImpl.java +++ b/io.openems.edge.core/src/io/openems/edge/core/sum/SumImpl.java @@ -73,6 +73,10 @@ public class SumImpl extends AbstractOpenemsComponent implements Sum, OpenemsCom POSTIVE, Sum.ChannelId.PRODUCTION_ACTIVE_POWER) // .add(Sum.ChannelId.CONSUMPTION_MAX_ACTIVE_POWER, "consumptionMaxActivePower", // POSTIVE, Sum.ChannelId.CONSUMPTION_ACTIVE_POWER) // + .add(Sum.ChannelId.ESS_MIN_DISCHARGE_POWER, "essMinDischargePower", // + NEGATIVE, Sum.ChannelId.ESS_DISCHARGE_POWER) // + .add(Sum.ChannelId.ESS_MAX_DISCHARGE_POWER, "essMaxDischargePower", // + POSTIVE, Sum.ChannelId.ESS_DISCHARGE_POWER) // .build(); @Override @@ -224,6 +228,7 @@ private void calculateChannelValues() { } else { essDcChargeEnergy.addValue(ess.getActiveChargeEnergyChannel()); essDcDischargeEnergy.addValue(ess.getActiveDischargeEnergyChannel()); + essDcDischargePower.addValue(ess.getActivePowerChannel()); } } else if (component instanceof ElectricityMeter meter) { diff --git a/io.openems.edge.core/test/io/openems/edge/app/evcs/TestEvcsCluster.java b/io.openems.edge.core/test/io/openems/edge/app/evcs/TestEvcsCluster.java index ca74d06dc97..c5d1dbd4297 100644 --- a/io.openems.edge.core/test/io/openems/edge/app/evcs/TestEvcsCluster.java +++ b/io.openems.edge.core/test/io/openems/edge/app/evcs/TestEvcsCluster.java @@ -51,6 +51,10 @@ public void beforeEach() throws Exception { this.kebaEvcs = Apps.kebaEvcs(t) // ); }, null, new PseudoComponentManagerFactory()); + + final var componentTask = this.appManagerTestBundle.addComponentAggregateTask(); + this.appManagerTestBundle.addSchedulerByCentralOrderAggregateTask(componentTask); + this.appManagerTestBundle.addStaticIpAggregateTask(); } @Test diff --git a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome.java b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome.java index 6db30b7b3ed..73a51874649 100644 --- a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome.java +++ b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome.java @@ -34,6 +34,9 @@ public void beforeEach() throws Exception { Apps::prepareBatteryExtension // ); }, null, new PseudoComponentManagerFactory()); + + final var componentTask = this.appManagerTestBundle.addComponentAggregateTask(); + this.appManagerTestBundle.addSchedulerByCentralOrderAggregateTask(componentTask); } @Test @@ -261,4 +264,24 @@ public static final JsonObject fullSettings() { .build(); } + /** + * Gets a {@link JsonObject} with the minimum settings for a + * {@link FeneconHome}. + * + * @return the settings object + */ + public static final JsonObject minSettings() { + return JsonUtils.buildJsonObject() // + .addProperty("SAFETY_COUNTRY", "GERMANY") // + .addProperty("RIPPLE_CONTROL_RECEIVER_ACTIV", false) // + .addProperty("MAX_FEED_IN_POWER", 1000) // + .addProperty("FEED_IN_SETTING", "LAGGING_0_95") // + .addProperty("HAS_AC_METER", false) // + .addProperty("HAS_DC_PV1", false) // + .addProperty("HAS_DC_PV2", false) // + .addProperty("HAS_EMERGENCY_RESERVE", false) // + .addProperty("SHADOW_MANAGEMENT_DISABLED", false) // + .build(); + } + } diff --git a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome20.java b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome20.java index 6d49b1ae66b..53bc17e0d65 100644 --- a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome20.java +++ b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome20.java @@ -35,6 +35,9 @@ public void beforeEach() throws Exception { Apps::prepareBatteryExtension // ); }, null, new PseudoComponentManagerFactory()); + + final var componentTask = this.appManagerTestBundle.addComponentAggregateTask(); + this.appManagerTestBundle.addSchedulerByCentralOrderAggregateTask(componentTask); } @Test diff --git a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30.java b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30.java index 95a08f05e07..1a32aa6ffeb 100644 --- a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30.java +++ b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30.java @@ -36,6 +36,9 @@ public void beforeEach() throws Exception { Apps::prepareBatteryExtension // ); }, null, new PseudoComponentManagerFactory()); + + final var componentTask = this.appManagerTestBundle.addComponentAggregateTask(); + this.appManagerTestBundle.addSchedulerByCentralOrderAggregateTask(componentTask); } @Test @@ -122,21 +125,21 @@ public void testEnableEmergency() throws Exception { assertNotNull(homeInstance); - this.appManagerTestBundle.assertExactSchedulerOrder("Initial Home 30 scheduler order", + this.appManagerTestBundle.scheduler.assertExactSchedulerOrder("Initial Home 30 scheduler order", "ctrlPrepareBatteryExtension0", "ctrlGridOptimizedCharge0", "ctrlEssSurplusFeedToGrid0", "ctrlBalancing0"); this.appManagerTestBundle.sut.handleUpdateAppInstanceRequest(DUMMY_ADMIN, new UpdateAppInstance.Request(homeInstance.instanceId, homeInstance.alias, fullSettings())); - this.appManagerTestBundle.assertExactSchedulerOrder("Update Home 30 to add emergency reserve", + this.appManagerTestBundle.scheduler.assertExactSchedulerOrder("Update Home 30 to add emergency reserve", "ctrlPrepareBatteryExtension0", "ctrlEmergencyCapacityReserve0", "ctrlGridOptimizedCharge0", "ctrlEssSurplusFeedToGrid0", "ctrlBalancing0"); this.appManagerTestBundle.sut.handleUpdateAppInstanceRequest(DUMMY_ADMIN, new UpdateAppInstance.Request( homeInstance.instanceId, homeInstance.alias, fullSettingsWithoutEmergencyReserve())); - this.appManagerTestBundle.assertExactSchedulerOrder("Update Home 30 to remove EmergencyReserve Controller", + this.appManagerTestBundle.scheduler.assertExactSchedulerOrder("Update Home 30 to remove EmergencyReserve Controller", "ctrlPrepareBatteryExtension0", "ctrlGridOptimizedCharge0", "ctrlEssSurplusFeedToGrid0", "ctrlBalancing0"); } @@ -264,7 +267,7 @@ public static final OpenemsAppInstance createFullHome30(AppManagerTestBundle app assertNotNull(homeInstance); appManagerTestBundle.assertNoValidationErrors(); - appManagerTestBundle.assertExactSchedulerOrder("Failed setting initial Home 30 Scheduler configuration", + appManagerTestBundle.scheduler.assertExactSchedulerOrder("Failed setting initial Home 30 Scheduler configuration", "ctrlPrepareBatteryExtension0", "ctrlEmergencyCapacityReserve0", "ctrlGridOptimizedCharge0", "ctrlEssSurplusFeedToGrid0", "ctrlBalancing0"); return homeInstance; diff --git a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30DefaultRelays.java b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30DefaultRelays.java index 0e609335512..0b96ddc28a3 100644 --- a/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30DefaultRelays.java +++ b/io.openems.edge.core/test/io/openems/edge/app/integratedsystem/TestFeneconHome30DefaultRelays.java @@ -40,6 +40,10 @@ public void beforeEach() throws Exception { Apps::thresholdControl // ); }, null, new PseudoComponentManagerFactory()); + + this.appManagerTestBundle + .addSchedulerByCentralOrderAggregateTask(this.appManagerTestBundle.addComponentAggregateTask()); + this.createFullHomeWithDummyIo(); } diff --git a/io.openems.edge.core/test/io/openems/edge/app/timeofusetariff/TestTibber.java b/io.openems.edge.core/test/io/openems/edge/app/timeofusetariff/TestTibber.java index 58f471cf588..a3e129b463c 100644 --- a/io.openems.edge.core/test/io/openems/edge/app/timeofusetariff/TestTibber.java +++ b/io.openems.edge.core/test/io/openems/edge/app/timeofusetariff/TestTibber.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.concurrent.ExecutionException; import java.util.stream.Stream; import org.junit.Before; @@ -21,6 +22,7 @@ import io.openems.common.jsonrpc.request.CreateComponentConfigRequest; import io.openems.common.jsonrpc.request.UpdateComponentConfigRequest; import io.openems.common.utils.JsonUtils; +import io.openems.edge.app.integratedsystem.TestFeneconHome; import io.openems.edge.core.appmanager.AppManagerTestBundle; import io.openems.edge.core.appmanager.AppManagerTestBundle.PseudoComponentManagerFactory; import io.openems.edge.core.appmanager.Apps; @@ -35,12 +37,20 @@ public class TestTibber { public void beforeEach() throws Exception { this.appManagerTestBundle = new AppManagerTestBundle(null, null, t -> { return ImmutableList.of(// - this.tibber = Apps.tibber(t)); + this.tibber = Apps.tibber(t), // + Apps.feneconHome(t) // + ); }, null, new PseudoComponentManagerFactory()); + + final var componentTask = this.appManagerTestBundle.addComponentAggregateTask(); + this.appManagerTestBundle.addSchedulerByCentralOrderAggregateTask(componentTask); + this.appManagerTestBundle.addPersistencePredictorAggregateTask(); } @Test public void testRemoveAccessToken() throws Exception { + this.installHome(); + final var properties = JsonUtils.buildJsonObject() // .addProperty("ACCESS_TOKEN", "g78aw9ht2n112nb453") // .build(); @@ -63,6 +73,7 @@ public void testRemoveAccessToken() throws Exception { @Test public void testAddChannelToPredictor() throws Exception { this.createPredictor(); + this.installHome(); final var properties = JsonUtils.buildJsonObject() // .addProperty("ACCESS_TOKEN", "g78aw9ht2n112nb453") // @@ -73,6 +84,15 @@ public void testAddChannelToPredictor() throws Exception { this.assertChannelsInPredictor("_sum/UnmanagedConsumptionActivePower"); } + @Test(expected = OpenemsNamedException.class) + public void testOnlyCompatibleWithHome() throws Exception { + final var properties = JsonUtils.buildJsonObject() // + .addProperty("ACCESS_TOKEN", "g78aw9ht2n112nb453") // + .build(); + this.appManagerTestBundle.sut.handleAddAppInstanceRequest(DUMMY_ADMIN, + new AddAppInstance.Request(this.tibber.getAppId(), "key", "alias", properties)).get(); + } + private void createPredictor() throws Exception { this.appManagerTestBundle.componentManger.handleJsonrpcRequest(DUMMY_ADMIN, new CreateComponentConfigRequest("Predictor.PersistenceModel", List.of(// @@ -82,6 +102,13 @@ private void createPredictor() throws Exception { ))).get(); } + private void installHome() throws InterruptedException, ExecutionException, OpenemsNamedException { + this.appManagerTestBundle.sut + .handleAddAppInstanceRequest(DUMMY_ADMIN, + new AddAppInstance.Request("App.FENECON.Home", "key", "alias", TestFeneconHome.minSettings())) + .get(); + } + private void assertChannelsInPredictor(String... channels) throws OpenemsNamedException { final var existingAddresses = this.getChannelsInPredictor(); final var expectedChannels = Stream.of(channels).collect(toSet()); diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImpSynchronizationTest.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImpSynchronizationTest.java index 9e2ec247557..7bdc17916be 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImpSynchronizationTest.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImpSynchronizationTest.java @@ -66,7 +66,7 @@ public void before() throws Exception { // create config for scheduler cm.getOrCreateEmptyConfiguration(componentManager.getEdgeConfig().getComponent("scheduler0").get().getPid()); - final var componentUtil = new ComponentUtilImpl(componentManager, cm); + final var componentUtil = new ComponentUtilImpl(componentManager); final var appManagerUtil = new AppManagerUtilImpl(componentManager); final var validator = new DummyValidator(); diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImplTest.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImplTest.java index 829ecf3c577..3e74b994890 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImplTest.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerImplTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import java.util.Hashtable; import java.util.TreeMap; import java.util.UUID; @@ -300,18 +299,13 @@ public void beforeEach() throws Exception { this.stromdao = Apps.stromdaoCorrently(t) // ); }); - - final var config = this.appManagerTestBundle.cm.getConfiguration( - this.appManagerTestBundle.componentManger.getEdgeConfig().getComponent("scheduler0").get().getPid(), - null); - final var props = new Hashtable(); - props.put("controllers.ids", new String[] { "ctrlPrepareBatteryExtension0", "ctrlGridOptimizedCharge0", - "ctrlEssSurplusFeedToGrid0", "ctrlBalancing0" }); - config.update(props); } @Test public void testAppValidateWorker() throws OpenemsException, Exception { + final var componentTask = this.appManagerTestBundle.addComponentAggregateTask(); + this.appManagerTestBundle.addSchedulerByCentralOrderAggregateTask(componentTask); + assertEquals(this.appManagerTestBundle.sut.instantiatedApps.size(), 4); this.appManagerTestBundle.assertNoValidationErrors(); diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerTestBundle.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerTestBundle.java index 07cf73eb56d..97ca72d496d 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerTestBundle.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/AppManagerTestBundle.java @@ -1,6 +1,5 @@ package io.openems.edge.core.appmanager; -import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -45,6 +44,17 @@ import io.openems.edge.core.appmanager.dependency.AppConfigValidator; import io.openems.edge.core.appmanager.dependency.AppManagerAppHelper; import io.openems.edge.core.appmanager.dependency.DependencyUtil; +import io.openems.edge.core.appmanager.dependency.aggregatetask.ComponentAggregateTask; +import io.openems.edge.core.appmanager.dependency.aggregatetask.ComponentAggregateTaskImpl; +import io.openems.edge.core.appmanager.dependency.aggregatetask.PersistencePredictorAggregateTask; +import io.openems.edge.core.appmanager.dependency.aggregatetask.PersistencePredictorAggregateTaskImpl; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerAggregateTask; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerAggregateTaskImpl; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderAggregateTask; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderAggregateTaskImpl; +import io.openems.edge.core.appmanager.dependency.aggregatetask.StaticIpAggregateTask; +import io.openems.edge.core.appmanager.dependency.aggregatetask.StaticIpAggregateTaskImpl; +import io.openems.edge.core.appmanager.dependency.aggregatetask.TestScheduler; import io.openems.edge.core.appmanager.jsonrpc.AddAppInstance; import io.openems.edge.core.appmanager.jsonrpc.AddAppInstance.Request; import io.openems.edge.core.appmanager.jsonrpc.DeleteAppInstance; @@ -63,6 +73,7 @@ public class AppManagerTestBundle { public final ComponentUtil componentUtil; public final Validator validator; + public final DummyAppManagerAppHelper appHelper; public final AppManagerImpl sut; public final AppManagerUtil appManagerUtil; public final AppCenterBackendUtil appCenterBackendUtil; @@ -71,6 +82,8 @@ public class AppManagerTestBundle { public final CheckablesBundle checkablesBundle; + public final TestScheduler scheduler; + public AppManagerTestBundle(JsonObject initialComponentConfig, MyConfig initialAppManagerConfig, Function> availableAppsSupplier) throws Exception { this(initialComponentConfig, initialAppManagerConfig, availableAppsSupplier, null, @@ -145,7 +158,7 @@ public AppManagerTestBundle(// this.cm.getOrCreateEmptyConfiguration( this.componentManger.getEdgeConfig().getComponent("scheduler0").get().getPid()); - this.componentUtil = new ComponentUtilImpl(this.componentManger, this.cm); + this.componentUtil = new ComponentUtilImpl(this.componentManger); this.sut = new AppManagerImpl() { @@ -229,9 +242,8 @@ private final void modifyWithCurrentConfig() throws OpenemsNamedException { dummyValidator.setCheckables(this.checkablesBundle.all()); this.validator = dummyValidator; - final var appManagerAppHelper = new DummyAppManagerAppHelper(this.componentManger, this.componentUtil, - this.appManagerUtil); - final var csoAppManagerAppHelper = cso((AppManagerAppHelper) appManagerAppHelper); + this.appHelper = new DummyAppManagerAppHelper(this.componentManger, this.componentUtil, this.appManagerUtil); + final var csoAppManagerAppHelper = cso((AppManagerAppHelper) this.appHelper); this.appValidateWorker = new AppValidateWorker(); final var appConfigValidator = new AppConfigValidator(); @@ -242,16 +254,14 @@ private final void modifyWithCurrentConfig() throws OpenemsNamedException { ReflectionUtils.setAttribute(AppConfigValidator.class, appConfigValidator, "appManagerUtil", this.appManagerUtil); - ReflectionUtils.setAttribute(AppConfigValidator.class, appConfigValidator, "tasks", - appManagerAppHelper.getTasks()); + ReflectionUtils.setAttribute(AppConfigValidator.class, appConfigValidator, "tasks", this.appHelper.getTasks()); // use this so the appManagerAppHelper does not has to be a OpenemsComponent and // the attribute can still be private - ReflectionUtils.setAttribute(appManagerAppHelper.getClass(), appManagerAppHelper, "appManager", this.sut); - ReflectionUtils.setAttribute(appManagerAppHelper.getClass(), appManagerAppHelper, "appManagerUtil", - this.appManagerUtil); + ReflectionUtils.setAttribute(this.appHelper.getClass(), this.appHelper, "appManager", this.sut); + ReflectionUtils.setAttribute(this.appHelper.getClass(), this.appHelper, "appManagerUtil", this.appManagerUtil); - ReflectionUtils.setAttribute(DependencyUtil.class, null, "appHelper", appManagerAppHelper); + ReflectionUtils.setAttribute(DependencyUtil.class, null, "appHelper", this.appHelper); new ComponentTest(this.sut) // .addReference("cm", this.cm) // @@ -262,6 +272,8 @@ private final void modifyWithCurrentConfig() throws OpenemsNamedException { .addReference("backendUtil", this.appCenterBackendUtil) // .addReference("availableApps", availableAppsSupplier.apply(this)) // .activate(initialAppManagerConfig); + + this.scheduler = new TestScheduler(this.componentManger); } /** @@ -364,21 +376,6 @@ public void assertComponentExist(EdgeConfig.Component component) throws OpenemsN } } - /** - * Checks if the given order of ids matches the order in the scheduler. - * - * @param message the identifying message for the {@link AssertionError} - * (null okay) - * @param orderIds the ids of components in the scheduler - * @throws IOException on IO-Error - */ - public void assertExactSchedulerOrder(String message, String... orderIds) throws IOException { - final var config = this.cm - .getConfiguration(this.componentManger.getEdgeConfig().getComponent("scheduler0").get().getPid(), null); - final var ids = (String[]) config.getProperties().get("controllers.ids"); - assertArrayEquals(message, orderIds, ids); - } - /** * Checks if all the given components exist. * @@ -391,6 +388,69 @@ public void assertComponentsExist(EdgeConfig.Component... components) throws Ope } } + /** + * Adds a {@link ComponentAggregateTask} to the current active tasks. + * + * @return the created {@link ComponentAggregateTask} + */ + public ComponentAggregateTask addComponentAggregateTask() { + final var componentAggregateTask = new ComponentAggregateTaskImpl(this.componentManger); + this.appHelper.addAggregateTask(componentAggregateTask); + return componentAggregateTask; + } + + /** + * Adds a {@link SchedulerAggregateTask} to the current active tasks. + * + * @param componentAggregateTask the {@link ComponentAggregateTask} + * @return the created {@link SchedulerAggregateTask} + */ + public SchedulerAggregateTask addSchedulerAggregateTask(ComponentAggregateTask componentAggregateTask) { + final var schedulerAggregateTaskImpl = new SchedulerAggregateTaskImpl(componentAggregateTask, + this.componentUtil); + this.appHelper.addAggregateTask(schedulerAggregateTaskImpl); + return schedulerAggregateTaskImpl; + } + + /** + * Adds a {@link SchedulerByCentralOrderAggregateTask} to the current active + * tasks. + * + * @param componentAggregateTask the {@link ComponentAggregateTask} + * @return the created {@link SchedulerByCentralOrderAggregateTask} + */ + public SchedulerByCentralOrderAggregateTask addSchedulerByCentralOrderAggregateTask( + ComponentAggregateTask componentAggregateTask) { + final var schedulerByCentralOrderAggregateTaskImpl = new SchedulerByCentralOrderAggregateTaskImpl( + this.componentManger, this.componentUtil, this.appManagerUtil, componentAggregateTask, + new SchedulerByCentralOrderAggregateTaskImpl.ProductionSchedulerOrderDefinition()); + this.appHelper.addAggregateTask(schedulerByCentralOrderAggregateTaskImpl); + return schedulerByCentralOrderAggregateTaskImpl; + } + + /** + * Adds a {@link StaticIpAggregateTask} to the current active tasks. + * + * @return the created {@link StaticIpAggregateTask} + */ + public StaticIpAggregateTask addStaticIpAggregateTask() { + var staticIpAggregateTaskImpl = new StaticIpAggregateTaskImpl(this.componentUtil); + this.appHelper.addAggregateTask(staticIpAggregateTaskImpl); + return staticIpAggregateTaskImpl; + } + + /** + * Adds a {@link PersistencePredictorAggregateTask} to the current active tasks. + * + * @return the created {@link PersistencePredictorAggregateTask} + */ + public PersistencePredictorAggregateTask addPersistencePredictorAggregateTask() { + final var persistencePredictorAggregateTaskImpl = new PersistencePredictorAggregateTaskImpl( + this.componentManger); + this.appHelper.addAggregateTask(persistencePredictorAggregateTaskImpl); + return persistencePredictorAggregateTaskImpl; + } + public record CheckablesBundle(// DummyValidator.TestCheckable checkTest, // CheckCardinality checkCardinality, // diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/Apps.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/Apps.java index 83fa62a0455..ac1de7ad14c 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/Apps.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/Apps.java @@ -17,6 +17,7 @@ import io.openems.edge.app.api.RestJsonApiReadOnly; import io.openems.edge.app.api.RestJsonApiReadWrite; import io.openems.edge.app.ess.FixActivePower; +import io.openems.edge.app.ess.PowerPlantController; import io.openems.edge.app.ess.PrepareBatteryExtension; import io.openems.edge.app.evcs.AlpitronicEvcs; import io.openems.edge.app.evcs.EvcsCluster; @@ -551,6 +552,16 @@ public static final PrepareBatteryExtension prepareBatteryExtension(AppManagerTe return app(t, PrepareBatteryExtension::new, "App.Ess.PrepareBatteryExtension"); } + /** + * Test method for creating a {@link PowerPlantController}. + * + * @param t the {@link AppManagerTestBundle} + * @return the {@link OpenemsApp} instance + */ + public static final PowerPlantController powerPlantController(AppManagerTestBundle t) { + return app(t, PowerPlantController::new, "App.Ess.PowerPlantController"); + } + private static final T app(AppManagerTestBundle t, DefaultAppConstructor constructor, String appId) { return constructor.create(t.componentManger, AppManagerTestBundle.getComponentContext(appId), t.cm, t.componentUtil); diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/ComponentUtilImplTest.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/ComponentUtilImplTest.java index 67ece83f750..8365a36e243 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/ComponentUtilImplTest.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/ComponentUtilImplTest.java @@ -27,7 +27,7 @@ public class ComponentUtilImplTest { public void before() throws Exception { this.componentManager = new DummyPseudoComponentManager(); this.cm = new DummyConfigurationAdmin(); - this.componentUtil = new ComponentUtilImpl(this.componentManager, this.cm); + this.componentUtil = new ComponentUtilImpl(this.componentManager); this.createTestRelay("io0"); } diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyAppManagerAppHelper.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyAppManagerAppHelper.java index b440ffd6e3c..9fe35111886 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyAppManagerAppHelper.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyAppManagerAppHelper.java @@ -1,6 +1,7 @@ package io.openems.edge.core.appmanager; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; import java.util.List; import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; @@ -12,10 +13,6 @@ import io.openems.edge.core.appmanager.dependency.TemporaryApps; import io.openems.edge.core.appmanager.dependency.UpdateValues; import io.openems.edge.core.appmanager.dependency.aggregatetask.AggregateTask; -import io.openems.edge.core.appmanager.dependency.aggregatetask.ComponentAggregateTaskImpl; -import io.openems.edge.core.appmanager.dependency.aggregatetask.PersistencePredictorAggregateTaskImpl; -import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerAggregateTaskImpl; -import io.openems.edge.core.appmanager.dependency.aggregatetask.StaticIpAggregateTaskImpl; public class DummyAppManagerAppHelper implements AppManagerAppHelper { @@ -28,17 +25,22 @@ public DummyAppManagerAppHelper(// ComponentUtil componentUtil, // AppManagerUtil util // ) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - final var componentTask = new ComponentAggregateTaskImpl(componentManager); - final var schedulerTask = new SchedulerAggregateTaskImpl(componentTask, componentUtil); - final var staticIpTask = new StaticIpAggregateTaskImpl(componentUtil); - final var persistencePredictorTask = new PersistencePredictorAggregateTaskImpl(componentManager); - this.tasks = List.of(staticIpTask, componentTask, schedulerTask, persistencePredictorTask); + this.tasks = new ArrayList>(); this.impl = new AppManagerAppHelperImpl(componentManager, componentUtil); ReflectionUtils.setAttribute(AppManagerAppHelperImpl.class, this.impl, "tasks", this.tasks); ReflectionUtils.setAttribute(AppManagerAppHelperImpl.class, this.impl, "appManagerUtil", util); } + /** + * Adds a {@link AggregateTask} to the current active ones. + * + * @param task the {@link AggregateTask} to add + */ + public void addAggregateTask(AggregateTask task) { + this.tasks.add(task); + } + public List> getTasks() { return this.tasks; } diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyPseudoComponentManager.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyPseudoComponentManager.java index b51dbc560c5..36f66c5f4ef 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyPseudoComponentManager.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/DummyPseudoComponentManager.java @@ -199,30 +199,7 @@ private CompletableFuture handleUpdateComponentConfigReq ) throws OpenemsNamedException { final var foundComponent = this.getPossiblyDisabledComponent(request.getComponentId()); - if (!(foundComponent instanceof DummyOpenemsComponent)) { - if (this.configurationAdmin == null) { - throw new OpenemsException("Can not update Component Config. ConfigurationAdmin is null!"); - } - try { - for (var configuration : this.configurationAdmin.listConfigurations(null)) { - final var props = configuration.getProperties(); - if (props == null) { - continue; - } - if (props.get("id") == null || !props.get("id").equals(request.getComponentId())) { - continue; - } - var properties = new Hashtable(); - for (var property : request.getProperties()) { - properties.put(property.getName(), property.getValue()); - } - configuration.update(properties); - } - return CompletableFuture.completedFuture(new GenericJsonrpcResponseSuccess(request.getId())); - } catch (IOException | InvalidSyntaxException e) { - throw new OpenemsException("Can not update Component Config."); - } - } else { + if (foundComponent instanceof DummyOpenemsComponent) { final var component = componentOf(// request.getComponentId(), // foundComponent.serviceFactoryPid(), // @@ -230,9 +207,30 @@ private CompletableFuture handleUpdateComponentConfigReq ); this.components.removeIf(t -> t.id().equals(request.getComponentId())); this.components.add(component); + return CompletableFuture.completedFuture(new GenericJsonrpcResponseSuccess(request.getId())); + } + if (this.configurationAdmin == null) { + throw new OpenemsException("Can not update Component Config. ConfigurationAdmin is null!"); + } + try { + for (var configuration : this.configurationAdmin.listConfigurations(null)) { + final var props = configuration.getProperties(); + if (props == null) { + continue; + } + if (props.get("id") == null || !props.get("id").equals(request.getComponentId())) { + continue; + } + var properties = new Hashtable(); + for (var property : request.getProperties()) { + properties.put(property.getName(), property.getValue()); + } + configuration.update(properties); + } + return CompletableFuture.completedFuture(new GenericJsonrpcResponseSuccess(request.getId())); + } catch (IOException | InvalidSyntaxException e) { + throw new OpenemsException("Can not update Component Config."); } - - return CompletableFuture.completedFuture(new GenericJsonrpcResponseSuccess(request.getId())); } private CompletableFuture handleDeleteComponentConfigRequest(// diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/TestTranslations.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/TestTranslations.java index ec23767c2ca..3b9a806c878 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/TestTranslations.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/TestTranslations.java @@ -131,6 +131,7 @@ public void beforeEach() throws Exception { this.apps.add(new TestTranslation(Apps.fixActivePower(t), true, JsonUtils.buildJsonObject() // .addProperty("ESS_ID", "ess0") // .build())); + this.apps.add(new TestTranslation(Apps.powerPlantController(t), true, new JsonObject())); this.apps.add(new TestTranslation(Apps.prepareBatteryExtension(t), true, new JsonObject())); return this.apps.stream().map(TestTranslation::app).toList(); }); diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImplTest.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImplTest.java index 661845668dd..5ce9359dd91 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImplTest.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerAggregateTaskImplTest.java @@ -1,24 +1,14 @@ package io.openems.edge.core.appmanager.dependency.aggregatetask; -import static io.openems.common.utils.JsonUtils.toJsonArray; import static io.openems.edge.common.test.DummyUser.DUMMY_ADMIN; import static java.util.Collections.emptyList; -import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertTrue; -import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; import org.junit.Before; import org.junit.Test; -import com.google.gson.JsonPrimitive; - -import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; -import io.openems.common.jsonrpc.request.UpdateComponentConfigRequest; import io.openems.common.session.Language; import io.openems.common.types.EdgeConfig; import io.openems.common.utils.JsonUtils; @@ -36,27 +26,20 @@ public class SchedulerAggregateTaskImplTest { private DummyConfigurationAdmin cm; private ComponentUtilImpl componentUtil; private ComponentAggregateTask aggregateTask; + private TestScheduler scheduler; @Before public void setUp() throws Exception { this.componentManager = new DummyPseudoComponentManager(); this.cm = new DummyConfigurationAdmin(); - this.componentUtil = new ComponentUtilImpl(this.componentManager, this.cm); + this.componentUtil = new ComponentUtilImpl(this.componentManager); this.componentManager.setConfigurationAdmin(this.cm); this.aggregateTask = new ComponentAggregateTaskImpl(this.componentManager); this.aggregateTask.reset(); this.task = new SchedulerAggregateTaskImpl(this.aggregateTask, this.componentUtil); this.task.reset(); - this.componentManager.addComponent(new EdgeConfig.Component("scheduler0", "", "Scheduler.AllAlphabetically", - JsonUtils.buildJsonObject() // - .addProperty("enabled", true) // - .add("controllers.ids", JsonUtils.buildJsonArray() // - .build()) - .build())); - // create config for scheduler - this.cm.getOrCreateEmptyConfiguration( - this.componentManager.getEdgeConfig().getComponent("scheduler0").get().getPid()); + this.scheduler = TestScheduler.create(this.componentManager); } @Test @@ -79,16 +62,16 @@ public void testCreate() throws Exception { this.task.aggregate(config, null); this.task.create(DUMMY_ADMIN, emptyList()); - this.assertExactSchedulerOrder("Ids in scheduler do not match!", config.componentOrder()); + this.scheduler.assertExactSchedulerOrder("Ids in scheduler do not match!", config.componentOrder()); } @Test public void testDelete() throws Exception { final var config = new SchedulerConfiguration("test0", "test1"); - this.setSchedulerIds(config.componentOrder()); + this.scheduler.setSchedulerIds(DUMMY_ADMIN, config.componentOrder()); this.task.aggregate(null, config); this.task.delete(DUMMY_ADMIN, emptyList()); - this.assertExactSchedulerOrder("Ids in scheduler got not removed!"); + this.scheduler.assertExactSchedulerOrder("Ids in scheduler got not removed!"); } @Test @@ -103,38 +86,20 @@ public void testGetGeneralFailMessage() { @Test public void testValidate() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("test0", "test", "Test.test", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("test1", "test", "Test.test", JsonUtils.buildJsonObject().build())); + final var config = AppConfiguration.create() // .addTask(Tasks.scheduler("test0", "test1")) // .build(); - this.setSchedulerIds(config.getConfiguration(SchedulerAggregateTask.class).componentOrder()); + this.scheduler.setSchedulerIds(DUMMY_ADMIN, + config.getConfiguration(SchedulerAggregateTask.class).componentOrder()); final var errors = new ArrayList(); this.task.validate(errors, config, config.getConfiguration(SchedulerAggregateTask.class)); assertTrue(errors.isEmpty()); } - private void assertExactSchedulerOrder(String message, List orderIds) throws IOException { - this.assertExactSchedulerOrder(message, orderIds.toArray(String[]::new)); - } - - private void assertExactSchedulerOrder(String message, String... orderIds) throws IOException { - final var config = this.cm.getConfiguration( - this.componentManager.getEdgeConfig().getComponent("scheduler0").get().getPid(), null); - final var ids = (String[]) config.getProperties().get("controllers.ids"); - assertArrayEquals(message, orderIds, ids); - } - - private void setSchedulerIds(List ids) - throws OpenemsNamedException, InterruptedException, ExecutionException { - this.setSchedulerIds(ids.toArray(String[]::new)); - } - - private void setSchedulerIds(String... ids) throws OpenemsNamedException, InterruptedException, ExecutionException { - this.componentManager.handleJsonrpcRequest(DUMMY_ADMIN, new UpdateComponentConfigRequest("scheduler0", List.of(// - new UpdateComponentConfigRequest.Property("controllers.ids", Arrays.stream(ids) // - .map(JsonPrimitive::new) // - .collect(toJsonArray())) // - ))).get(); - } - } diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImplTest.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImplTest.java new file mode 100644 index 00000000000..b692317f4bf --- /dev/null +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerByCentralOrderAggregateTaskImplTest.java @@ -0,0 +1,337 @@ +package io.openems.edge.core.appmanager.dependency.aggregatetask; + +import static io.openems.edge.common.test.DummyUser.DUMMY_ADMIN; +import static java.util.Collections.emptyList; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; + +import io.openems.common.session.Language; +import io.openems.common.types.EdgeConfig; +import io.openems.common.utils.JsonUtils; +import io.openems.edge.core.appmanager.AppConfiguration; +import io.openems.edge.core.appmanager.AppManagerTestBundle; +import io.openems.edge.core.appmanager.AppManagerTestBundle.PseudoComponentManagerFactory; +import io.openems.edge.core.appmanager.DummyApp; +import io.openems.edge.core.appmanager.DummyPseudoComponentManager; +import io.openems.edge.core.appmanager.TranslationUtil; +import io.openems.edge.core.appmanager.dependency.Tasks; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderAggregateTaskImpl.SchedulerOrderDefinition; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; +import io.openems.edge.core.appmanager.jsonrpc.AddAppInstance; + +public class SchedulerByCentralOrderAggregateTaskImplTest { + + private SchedulerByCentralOrderAggregateTask task; + + private AppManagerTestBundle testBundle; + private DummyPseudoComponentManager componentManager; + private ComponentAggregateTask componentTask; + + @Before + public void setUp() throws Exception { + final var componentManagerFactory = new PseudoComponentManagerFactory(); + this.testBundle = new AppManagerTestBundle(null, null, tb -> { + return ImmutableList.of(DummyApp.create() // + .setAppId("appId") // + .setConfiguration((t, u, s) -> AppConfiguration.create() // + .addTask(Tasks.component(new EdgeConfig.Component("id0", "alias", "factoryId", + JsonUtils.buildJsonObject().build()))) // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent("id0", "factoryId", "appId"))) // + .build()) + .build(), + DummyApp.create() // + .setAppId("appId2") // + .setConfiguration((t, u, s) -> AppConfiguration.create() // + .addTask(Tasks.component(new EdgeConfig.Component("id1", "alias", "factoryId1", + JsonUtils.buildJsonObject().build()))) // + .addTask(Tasks.schedulerByCentralOrder( + new SchedulerComponent("id1", "factoryId1", "appId2"))) // + .build()) + .build()); + }, null, componentManagerFactory); + this.componentManager = componentManagerFactory.getComponentManager(); + + this.componentTask = this.testBundle.addComponentAggregateTask(); + this.componentTask.reset(); + this.task = new SchedulerByCentralOrderAggregateTaskImpl(// + this.testBundle.componentManger, // + this.testBundle.componentUtil, // + this.testBundle.appManagerUtil, // + this.componentTask, // + new SchedulerOrderDefinition() // + .thenByFactoryId("factoryId") // + .thenByFactoryId("factoryId1") // + .thenByFactoryId("factoryId2") // + .thenByFactoryId("factoryId3") // + ); + this.task.reset(); + this.testBundle.appHelper.addAggregateTask(this.task); + } + + @Test + public void testAggregate() { + final var config = new SchedulerByCentralOrderConfiguration(); + + this.task.aggregate(null, null); + this.task.aggregate(config, null); + this.task.aggregate(null, config); + this.task.aggregate(config, config); + } + + @Test + public void testCreate() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("id0", "alias", "factoryId1", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id1", "alias", "factoryId2", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id2", "alias", "factoryId3", JsonUtils.buildJsonObject().build())); + + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id0", "factoryId1", "appId"), // + new SchedulerComponent("id2", "factoryId3", "appId"), // + new SchedulerComponent("id1", "factoryId2", "appId") // + ); + + this.task.aggregate(config, null); + this.task.create(DUMMY_ADMIN, emptyList()); + + this.testBundle.scheduler.assertExactSchedulerOrder("Ids got not added in Scheduler", "id0", "id1", "id2"); + } + + @Test + public void testCreateInsertIntoExistingTop() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("id0", "alias", "factoryId1", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id1", "alias", "factoryId2", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id2", "alias", "factoryId3", JsonUtils.buildJsonObject().build())); + + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id1", "id2"); + + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id0", "factoryId1", "appId") // + ); + + this.task.aggregate(config, null); + this.task.create(DUMMY_ADMIN, emptyList()); + + this.testBundle.scheduler.assertExactSchedulerOrder("Ids got not added in Scheduler", "id0", "id1", "id2"); + } + + @Test + public void testCreateInsertIntoExistingCenter() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("id0", "alias", "factoryId1", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id1", "alias", "factoryId2", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id2", "alias", "factoryId3", JsonUtils.buildJsonObject().build())); + + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id0", "id2"); + + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id1", "factoryId2", "appId") // + ); + + this.task.aggregate(config, null); + this.task.create(DUMMY_ADMIN, emptyList()); + + this.testBundle.scheduler.assertExactSchedulerOrder("Ids got not added in Scheduler", "id0", "id1", "id2"); + } + + @Test + public void testCreateInsertIntoExistingBottom() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("id0", "alias", "factoryId1", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id1", "alias", "factoryId2", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id2", "alias", "factoryId3", JsonUtils.buildJsonObject().build())); + + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id0", "id1"); + + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id2", "factoryId3", "appId") // + ); + + this.task.aggregate(config, null); + this.task.create(DUMMY_ADMIN, emptyList()); + + this.testBundle.scheduler.assertExactSchedulerOrder("Ids got not added in Scheduler", "id0", "id1", "id2"); + } + + @Test + public void testCreateInsertIntoExistingWithUndefinedIds() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("id0", "alias", "factoryId1", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id1", "alias", "undefinedFactoryId", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id2", "alias", "factoryId2", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id3", "alias", "factoryId3", JsonUtils.buildJsonObject().build())); + + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id0", "id1", "id3"); + + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id2", "factoryId2", "appId") // + ); + + this.task.aggregate(config, null); + this.task.create(DUMMY_ADMIN, emptyList()); + + this.testBundle.scheduler.assertExactSchedulerOrder("Ids got not added in Scheduler", "id0", "id1", "id2", + "id3"); + } + + @Test + public void testCreateInsertIntoExistingWithNotExistingComponent() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("id0", "alias", "factoryId1", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id2", "alias", "factoryId2", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id3", "alias", "factoryId3", JsonUtils.buildJsonObject().build())); + + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id0", "id1", "id3"); + + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id2", "factoryId2", "appId") // + ); + + this.task.aggregate(config, null); + this.task.create(DUMMY_ADMIN, emptyList()); + + this.testBundle.scheduler.assertExactSchedulerOrder("Ids got not added in Scheduler", "id0", "id1", "id2", + "id3"); + } + + @Test + public void testCreateRescheduleWronlyConfigured() throws Exception { + this.componentManager.addComponent( + new EdgeConfig.Component("id0", "alias", "factoryId1", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id1", "alias", "factoryId2", JsonUtils.buildJsonObject().build())); + this.componentManager.addComponent( + new EdgeConfig.Component("id2", "alias", "factoryId3", JsonUtils.buildJsonObject().build())); + + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id2", "id0", "id1"); + + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id2", "factoryId3", "appId") // + ); + + this.task.aggregate(config, null); + this.task.create(DUMMY_ADMIN, emptyList()); + + this.testBundle.scheduler.assertExactSchedulerOrder("Ids got not added in Scheduler", "id0", "id1", "id2"); + } + + @Test + public void testDelete() throws Exception { + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id0", "factoryId1", "appId") // + ); + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id0"); + this.task.aggregate(null, config); + this.task.delete(DUMMY_ADMIN, emptyList()); + this.testBundle.scheduler.assertExactSchedulerOrder("Ids in scheduler got not removed!"); + } + + @Test + public void testDeleteOfStillUsedId() throws Exception { + final var config = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id0", "factoryId1", "appId") // + ); + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id0"); + this.task.aggregate(null, config); + this.task.delete(DUMMY_ADMIN, List.of(AppConfiguration.create() // + .addTask(Tasks.schedulerByCentralOrder(new SchedulerComponent("id0", "factoryId1", "otherAppId"))) // + .build())); + this.testBundle.scheduler.assertExactSchedulerOrder("Ids in scheduler got not removed!", "id0"); + } + + @Test + public void testGetGeneralFailMessage() { + final var dt = TranslationUtil.enableDebugMode(); + + for (var l : Language.values()) { + this.task.getGeneralFailMessage(l); + } + assertTrue(dt.getMissingKeys().isEmpty()); + } + + @Test + public void testValidate() throws Exception { + this.testBundle.sut.handleAddAppInstanceRequest(DUMMY_ADMIN, + new AddAppInstance.Request("appId", "key", "alias", JsonUtils.buildJsonObject().build())).get(); + + final var schedulerConfig = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id0", "factoryId", "appId") // + ); + final var config = AppConfiguration.create() // + .addTask(Tasks.schedulerByCentralOrder(schedulerConfig.componentOrder())) // + .build(); + + final var errors = new ArrayList(); + this.task.validate(errors, config, schedulerConfig); + + assertTrue("Validation should be successful but got: " + String.join(", ", errors), errors.isEmpty()); + } + + @Test + public void testValidateMissingIds() throws Exception { + this.testBundle.sut.handleAddAppInstanceRequest(DUMMY_ADMIN, + new AddAppInstance.Request("appId", "key", "alias", JsonUtils.buildJsonObject().build())).get(); + + // remove ids from scheduler + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN); + + final var schedulerConfig = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id0", "factoryId", "appId") // + ); + final var config = AppConfiguration.create() // + .addTask(Tasks.schedulerByCentralOrder(schedulerConfig.componentOrder())) // + .build(); + + final var errors = new ArrayList(); + this.task.validate(errors, config, schedulerConfig); + + assertFalse("Validation should not be successful but got: " + String.join(", ", errors), errors.isEmpty()); + } + + @Test + public void testValidateWronglyConfiguredIds() throws Exception { + this.testBundle.sut.handleAddAppInstanceRequest(DUMMY_ADMIN, + new AddAppInstance.Request("appId", "key", "alias", JsonUtils.buildJsonObject().build())).get(); + this.testBundle.sut + .handleAddAppInstanceRequest(DUMMY_ADMIN, + new AddAppInstance.Request("appId2", "key", "alias", JsonUtils.buildJsonObject().build())) + .get(); + + this.testBundle.scheduler.setSchedulerIds(DUMMY_ADMIN, "id1", "id0"); + + final var schedulerConfig = new SchedulerByCentralOrderConfiguration(// + new SchedulerComponent("id0", "factoryId", "appId") // + ); + final var config = AppConfiguration.create() // + .addTask(Tasks.schedulerByCentralOrder(schedulerConfig.componentOrder())) // + .build(); + + final var errors = new ArrayList(); + this.task.validate(errors, config, schedulerConfig); + + assertFalse("Validation should not be successful but got: " + String.join(", ", errors), errors.isEmpty()); + } + +} diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerOrderDefinitionTest.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerOrderDefinitionTest.java new file mode 100644 index 00000000000..9e5b608130b --- /dev/null +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/SchedulerOrderDefinitionTest.java @@ -0,0 +1,198 @@ +package io.openems.edge.core.appmanager.dependency.aggregatetask; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.junit.Test; + +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderAggregateTaskImpl.SchedulerOrderDefinition; +import io.openems.edge.core.appmanager.dependency.aggregatetask.SchedulerByCentralOrderConfiguration.SchedulerComponent; + +public class SchedulerOrderDefinitionTest { + + @Test + public void testOrderByFactoryId() { + final var order = new SchedulerOrderDefinition() // + .thenByFactoryId("1") // + .thenByFactoryId("2") // + .thenByFactoryId("3") // + .thenByFactoryId("4"); + + final var items = List.of(// + new SchedulerComponent("", "1", ""), // + new SchedulerComponent("", "2", ""), // + new SchedulerComponent("", "3", ""), // + new SchedulerComponent("", "4", "")); + + forEachCombination(items, () -> new TreeSet<>(order), combination -> { + final var iterator = combination.iterator(); + + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "1", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "2", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "3", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "4", ""), iterator.next()); + + assertFalse(iterator.hasNext()); + }); + } + + @Test + public void testOrderByCreatedAppId() { + final var order = new SchedulerOrderDefinition() // + .thenByCreatedAppId("1") // + .thenByCreatedAppId("2") // + .thenByCreatedAppId("3") // + .thenByCreatedAppId("4"); + + final var items = List.of(// + new SchedulerComponent("", "", "1"), // + new SchedulerComponent("", "", "2"), // + new SchedulerComponent("", "", "3"), // + new SchedulerComponent("", "", "4")); + + forEachCombination(items, () -> new TreeSet<>(order), combination -> { + final var iterator = combination.iterator(); + + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "", "1"), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "", "2"), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "", "3"), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "", "4"), iterator.next()); + + assertFalse(iterator.hasNext()); + }); + } + + @Test + public void testOrderWithNestedOrder() { + final var order = new SchedulerOrderDefinition() // + .thenByFactoryId("1") // + .thenBy(new SchedulerOrderDefinition() // + .thenByFactoryId("2") // + .thenByFactoryId("3")) // + .thenByFactoryId("4"); + + final var items = List.of(// + new SchedulerComponent("", "1", ""), // + new SchedulerComponent("", "2", ""), // + new SchedulerComponent("", "3", ""), // + new SchedulerComponent("", "4", "")); + + forEachCombination(items, () -> new TreeSet<>(order), combination -> { + final var iterator = combination.iterator(); + + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "1", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "2", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "3", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "4", ""), iterator.next()); + + assertFalse(iterator.hasNext()); + }); + } + + @Test + public void testOrderWithFilter() { + final var order = new SchedulerOrderDefinition() // + .thenByFactoryId("1") // + .thenBy(new SchedulerOrderDefinition() // + .filterByFactoryId("2") // + .thenByCreatedAppId("1") // + .thenByCreatedAppId("2")) // + .thenByFactoryId("3"); + + final var items = List.of(// + new SchedulerComponent("", "1", ""), // + new SchedulerComponent("", "2", "1"), // + new SchedulerComponent("", "2", "2"), // + new SchedulerComponent("", "3", "")); + + forEachCombination(items, () -> new TreeSet<>(order), combination -> { + final var iterator = combination.iterator(); + + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "1", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "2", "1"), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "2", "2"), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "3", ""), iterator.next()); + + assertFalse(iterator.hasNext()); + }); + } + + @Test + public void testOrderWithRest() { + final var order = new SchedulerOrderDefinition() // + .thenByFactoryId("1") // + .thenBy(new SchedulerOrderDefinition() // + .filterByFactoryId("2") // + .thenByCreatedAppId("1") // + .rest()) // + .thenByFactoryId("3"); + + final var items = List.of(// + new SchedulerComponent("", "1", ""), // + new SchedulerComponent("", "2", "1"), // + new SchedulerComponent("", "2", "2"), // + new SchedulerComponent("", "3", "")); + + forEachCombination(items, () -> new TreeSet<>(order), combination -> { + final var iterator = combination.iterator(); + + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "1", ""), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "2", "1"), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "2", "2"), iterator.next()); + assertTrue(iterator.hasNext()); + assertEquals(new SchedulerComponent("", "3", ""), iterator.next()); + + assertFalse(iterator.hasNext()); + }); + } + + private static void forEachCombination(// + final List items, // + final Supplier> setSupplier, // + final Consumer> onEachCombination // + ) { + if (items.size() == 1) { + final var set = setSupplier.get(); + set.add(items.get(0)); + onEachCombination.accept(set); + return; + } + for (int i = 0; i < items.size(); i++) { + final var currentItem = items.get(i); + final var sublist = new ArrayList<>(items); + sublist.remove(i); + forEachCombination(sublist, () -> { + final var set = setSupplier.get(); + set.add(currentItem); + return set; + }, onEachCombination); + } + } +} diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/StaticIpAggregateTaskImplTest.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/StaticIpAggregateTaskImplTest.java index 33ac7ce96ec..e6c5a53a29d 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/StaticIpAggregateTaskImplTest.java +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/StaticIpAggregateTaskImplTest.java @@ -22,7 +22,7 @@ public class StaticIpAggregateTaskImplTest { public void setUp() throws Exception { this.componentManager = new DummyPseudoComponentManager(); this.cm = new DummyConfigurationAdmin(); - this.componentUtil = new ComponentUtilImpl(this.componentManager, this.cm); + this.componentUtil = new ComponentUtilImpl(this.componentManager); this.componentManager.setConfigurationAdmin(this.cm); this.task = new StaticIpAggregateTaskImpl(this.componentUtil); this.task.reset(); diff --git a/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/TestScheduler.java b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/TestScheduler.java new file mode 100644 index 00000000000..8ce40d13df9 --- /dev/null +++ b/io.openems.edge.core/test/io/openems/edge/core/appmanager/dependency/aggregatetask/TestScheduler.java @@ -0,0 +1,93 @@ +package io.openems.edge.core.appmanager.dependency.aggregatetask; + +import static io.openems.common.utils.JsonUtils.toJsonArray; +import static java.util.stream.Collectors.joining; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; + +import com.google.gson.JsonPrimitive; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.jsonrpc.request.UpdateComponentConfigRequest; +import io.openems.common.types.EdgeConfig; +import io.openems.common.utils.JsonUtils; +import io.openems.edge.common.component.ComponentManager; +import io.openems.edge.common.user.User; +import io.openems.edge.core.appmanager.DummyPseudoComponentManager; + +public class TestScheduler { + + /** + * Adds a scheduler to the current components and creates a + * {@link TestScheduler} object. + * + * @param componentManager the {@link DummyPseudoComponentManager} to add the + * scheduler + * @return the {@link TestScheduler} + */ + public static TestScheduler create(DummyPseudoComponentManager componentManager) { + componentManager.addComponent(new EdgeConfig.Component("scheduler0", "", "Scheduler.AllAlphabetically", + JsonUtils.buildJsonObject() // + .addProperty("enabled", true) // + .add("controllers.ids", JsonUtils.buildJsonArray() // + .build()) + .build())); + return new TestScheduler(componentManager); + } + + private final ComponentManager componentManager; + + public TestScheduler(ComponentManager componentManager) { + super(); + this.componentManager = componentManager; + } + + /** + * Checks if the given order of ids matches the order in the scheduler. + * + * @param message the identifying message for the {@link AssertionError} + * @param expectedIds the expected ids in the scheduler + * @throws OpenemsNamedException on error + */ + public void assertExactSchedulerOrder(String message, List expectedIds) throws OpenemsNamedException { + this.assertExactSchedulerOrder(message, expectedIds.toArray(String[]::new)); + } + + /** + * Checks if the given order of ids matches the order in the scheduler. + * + * @param message the identifying message for the {@link AssertionError} + * @param orderIds the ids of components in the scheduler + * @throws OpenemsNamedException on error + */ + public void assertExactSchedulerOrder(String message, String... orderIds) throws OpenemsNamedException { + final var scheduler = this.componentManager.getComponent("scheduler0"); + final var ids = (Object[]) scheduler.getComponentContext().getProperties().get("controllers.ids"); + if (ids == null) { + assertTrue(orderIds.length == 0); + return; + } + assertArrayEquals(message + ": was [" + Stream.of(ids).map(Object::toString).collect(joining(", ")) + + "] expected [" + String.join(", ", orderIds) + "]", orderIds, ids); + } + + public void setSchedulerIds(User user, List ids) + throws OpenemsNamedException, InterruptedException, ExecutionException { + this.setSchedulerIds(user, ids.toArray(String[]::new)); + } + + public void setSchedulerIds(User user, String... ids) + throws OpenemsNamedException, InterruptedException, ExecutionException { + this.componentManager.handleJsonrpcRequest(user, new UpdateComponentConfigRequest("scheduler0", List.of(// + new UpdateComponentConfigRequest.Property("controllers.ids", Arrays.stream(ids) // + .map(JsonPrimitive::new) // + .collect(toJsonArray())) // + ))).get(); + } + +} diff --git a/io.openems.edge.core/test/io/openems/edge/core/host/jsonrpc/ExecuteSystemResponseTest.java b/io.openems.edge.core/test/io/openems/edge/core/host/jsonrpc/ExecuteSystemResponseTest.java new file mode 100644 index 00000000000..5993afe4fda --- /dev/null +++ b/io.openems.edge.core/test/io/openems/edge/core/host/jsonrpc/ExecuteSystemResponseTest.java @@ -0,0 +1,34 @@ +package io.openems.edge.core.host.jsonrpc; + +import static io.openems.common.utils.JsonUtils.buildJsonObject; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; +import io.openems.common.exceptions.OpenemsException; +import io.openems.common.jsonrpc.base.GenericJsonrpcRequest; +import io.openems.edge.core.host.jsonrpc.ExecuteSystemRestartRequest.Type; + +public class ExecuteSystemResponseTest { + + @Test + public void testParse() throws OpenemsNamedException { + var sut = ExecuteSystemRestartRequest.from(new GenericJsonrpcRequest("executeSystemRestart", buildJsonObject() // + .addProperty("type", "soft") // + .build())); + assertEquals(Type.SOFT, sut.type); + + sut = ExecuteSystemRestartRequest.from(new GenericJsonrpcRequest("executeSystemRestart", buildJsonObject() // + .addProperty("type", "HARD") // + .build())); + assertEquals(Type.HARD, sut.type); + } + + @Test(expected = OpenemsException.class) + public void testParseFailed() throws OpenemsNamedException { + ExecuteSystemRestartRequest.from(new GenericJsonrpcRequest("executeSystemRestart", buildJsonObject() // + .addProperty("type", "foo") // + .build())); + } +} diff --git a/io.openems.edge.core/test/io/openems/edge/core/sum/MyConfig.java b/io.openems.edge.core/test/io/openems/edge/core/sum/MyConfig.java index c0a24ed7b09..b51a39c2170 100644 --- a/io.openems.edge.core/test/io/openems/edge/core/sum/MyConfig.java +++ b/io.openems.edge.core/test/io/openems/edge/core/sum/MyConfig.java @@ -11,6 +11,8 @@ public static class Builder { private int gridMinActivePower; private int gridMaxActivePower; private int productionMaxActivePower; + private int essMinDischargePower; + private int essMaxDischargePower; private int consumptionMaxActivePower; private String[] ignoreStateComponents; @@ -32,6 +34,16 @@ public Builder setProductionMaxActivePower(int productionMaxActivePower) { return this; } + public Builder setEssMinDischargePower(int setEssMinDischargePower) { + this.essMinDischargePower = setEssMinDischargePower; + return this; + } + + public Builder setEssMaxDischargePower(int setEssMaxDischargePower) { + this.essMaxDischargePower = setEssMaxDischargePower; + return this; + } + public Builder setConsumptionMaxActivePower(int consumptionMaxActivePower) { this.consumptionMaxActivePower = consumptionMaxActivePower; return this; @@ -73,6 +85,16 @@ public int gridMaxActivePower() { return this.builder.gridMaxActivePower; } + @Override + public int essMinDischargePower() { + return this.builder.essMinDischargePower; + } + + @Override + public int essMaxDischargePower() { + return this.builder.essMaxDischargePower; + } + @Override public int productionMaxActivePower() { return this.builder.productionMaxActivePower; diff --git a/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/Config.java b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/Config.java index 8bb032212a7..964f2be8c5e 100644 --- a/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/Config.java +++ b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/Config.java @@ -19,6 +19,15 @@ @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") boolean enabled() default true; + @AttributeDefinition(name = "Select the grid meter category.", description = "Select grid meter category (Commercial Meter only valid for ETT-Systems e.g. GoodWe 20/30)") + GoodWeGridMeterCategory goodWeMeterCategory() default GoodWeGridMeterCategory.SMART_METER; + + @AttributeDefinition(name = "First CT-Ratio Value of external meter (Only for goodWeMeterCategory=COMMERCIAL_METER)", description = "First CT-Ratio Value(eg. \"200\":5 A) of external (eg. Commercial/Business) meter. (Available only for ETT-Systems)") + int externalMeterRatioValueA() default 0; + + @AttributeDefinition(name = "Second CT-Ratio Value of external meter (Only for goodWeMeterCategory=COMMERCIAL_METER).", description = "Second CT-Ratio Value(eg. 200:\"5\" A) of external (eg. Commercial/Business) meter. (Available only for ETT-Systems)") + int externalMeterRatioValueB() default 5; + @AttributeDefinition(name = "Modbus-ID", description = "ID of Modbus bridge.") String modbus_id() default "modbus0"; diff --git a/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeter.java b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeter.java index 0b816de2e35..81ffcc911d5 100644 --- a/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeter.java +++ b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeter.java @@ -1,9 +1,11 @@ package io.openems.edge.goodwe.gridmeter; +import io.openems.common.channel.AccessMode; import io.openems.common.channel.Level; import io.openems.common.channel.Unit; import io.openems.common.types.OpenemsType; import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.channel.IntegerWriteChannel; import io.openems.edge.common.channel.StateChannel; import io.openems.edge.common.channel.value.Value; import io.openems.edge.common.component.OpenemsComponent; @@ -49,7 +51,10 @@ public static enum ChannelId implements io.openems.edge.common.channel.ChannelId METER_CON_REVERSE_L3(Doc.of(Level.WARNING) // .text("L3 (Phase S) - Connected reverse")), // METER_CON_INCORRECTLY_L3(Doc.of(Level.WARNING) // - .text("L3 (Phase S) - Connected incorrectly")); // + .text("L3 (Phase S) - Connected incorrectly")), + EXTERNAL_METER_RATIO(Doc.of(OpenemsType.INTEGER) // + .accessMode(AccessMode.READ_WRITE) + .text("External meter ratio (e.g. the selected CT is 3000A:5A, the CT ratio value is 600")); // private final Doc doc; @@ -81,4 +86,12 @@ public default Value getHasNoMeter() { return this.getHasNoMeterChannel().value(); } + /** + * Gets the Channel for {@link ChannelId#EXTERNAL_METER_RATIO}. + * + * @return the Channel + */ + public default IntegerWriteChannel getExternalMeterRatioChannel() { + return this.channel(ChannelId.EXTERNAL_METER_RATIO); + } } diff --git a/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterCategory.java b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterCategory.java new file mode 100644 index 00000000000..4fe5deff296 --- /dev/null +++ b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterCategory.java @@ -0,0 +1,5 @@ +package io.openems.edge.goodwe.gridmeter; + +public enum GoodWeGridMeterCategory { + SMART_METER, COMMERCIAL_METER +} diff --git a/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImpl.java b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImpl.java index 557d8548304..67a2a6accf3 100644 --- a/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImpl.java +++ b/io.openems.edge.goodwe/src/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImpl.java @@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory; import io.openems.common.channel.AccessMode; +import io.openems.common.exceptions.OpenemsError.OpenemsNamedException; import io.openems.common.exceptions.OpenemsException; import io.openems.common.types.OpenemsType; import io.openems.edge.bridge.modbus.api.AbstractOpenemsModbusComponent; @@ -34,9 +35,10 @@ import io.openems.edge.bridge.modbus.api.element.DummyRegisterElement; import io.openems.edge.bridge.modbus.api.element.SignedDoublewordElement; import io.openems.edge.bridge.modbus.api.element.SignedWordElement; -import io.openems.edge.bridge.modbus.api.element.StringWordElement; import io.openems.edge.bridge.modbus.api.element.UnsignedWordElement; import io.openems.edge.bridge.modbus.api.task.FC3ReadRegistersTask; +import io.openems.edge.bridge.modbus.api.task.FC6WriteRegisterTask; +import io.openems.edge.common.channel.ChannelUtils; import io.openems.edge.common.component.OpenemsComponent; import io.openems.edge.common.event.EdgeEventConstants; import io.openems.edge.common.modbusslave.ModbusSlave; @@ -60,6 +62,7 @@ "type=GRID" // }) @EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE, // EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE // }) public class GoodWeGridMeterImpl extends AbstractOpenemsModbusComponent implements GoodWeGridMeter, ElectricityMeter, @@ -71,6 +74,8 @@ public class GoodWeGridMeterImpl extends AbstractOpenemsModbusComponent implemen private final CalculateEnergyFromPower calculateConsumptionEnergy = new CalculateEnergyFromPower(this, ElectricityMeter.ChannelId.ACTIVE_CONSUMPTION_ENERGY); + private Config config; + @Reference private ConfigurationAdmin cm; @@ -99,6 +104,7 @@ public GoodWeGridMeterImpl() { @Activate private void activate(ComponentContext context, Config config) throws OpenemsException { + this.config = config; if (super.activate(context, config.id(), config.alias(), config.enabled(), config.modbusUnitId(), this.cm, "Modbus", config.modbus_id())) { return; @@ -172,39 +178,22 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException { ModbusUtils.readELementOnce(protocol, new UnsignedWordElement(35016), true) // .thenAccept(dspVersion -> { try { - if (dspVersion >= 4) { + if (dspVersion >= 4 || dspVersion == 0) { this.handleDspVersion4(protocol); } - // Handle beta versions - if (dspVersion == 0) { - - // Handle GoodWe Types - ModbusUtils.readELementOnce(protocol, new StringWordElement(35003, 8), true) // - .thenAccept(serialNr -> { - try { - Integer version = TypeUtils.getAsType(OpenemsType.INTEGER, - serialNr.substring(2, 4)); - - // TODO: Handle GoodWe - // Handle GoodWe 20-30 - if (version != null && version >= 20) { - this.handleDspVersion4(protocol); - } - - } catch (OpenemsException e) { - this.logError(this.log, "Unable to add task for modbus protocol"); - e.printStackTrace(); - } - }); - } - } catch (OpenemsException e) { this.logError(this.log, "Unable to add task for modbus protocol"); e.printStackTrace(); } }); + switch (this.config.goodWeMeterCategory()) { + case COMMERCIAL_METER -> this.handleExternalMeter(protocol); + case SMART_METER -> { + } + } + return protocol; } @@ -231,13 +220,63 @@ private void handleDspVersion4(ModbusProtocol protocol) throws OpenemsException this.ignoreZeroAndScaleFactor2))); // } + private void handleExternalMeter(ModbusProtocol protocol) throws OpenemsException { + + protocol.addTask(// + new FC6WriteRegisterTask(47456, + m(GoodWeGridMeter.ChannelId.EXTERNAL_METER_RATIO, new UnsignedWordElement(47456)) // + )); // + + protocol.addTask(// + new FC3ReadRegistersTask(47456, Priority.LOW, // + m(GoodWeGridMeter.ChannelId.EXTERNAL_METER_RATIO, new UnsignedWordElement(47456)) // + )); // + } + @Override public void handleEvent(Event event) { switch (event.getTopic()) { - case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE: - this.calculateEnergy(); - break; + case EdgeEventConstants.TOPIC_CYCLE_BEFORE_PROCESS_IMAGE -> { + + switch (this.config.goodWeMeterCategory()) { + case COMMERCIAL_METER -> this.setExternalMeterValue(); + case SMART_METER -> { + } + } } + case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE -> this.calculateEnergy(); + } + } + + /** + * Set channel for external meter if configured. + */ + protected void setExternalMeterValue() { + final var meterCtRatio = calculateRatio(this.config.externalMeterRatioValueA(), + this.config.externalMeterRatioValueB()); + + try { + ChannelUtils.setWriteValueIfNotRead(this.getExternalMeterRatioChannel(), meterCtRatio); + } catch (OpenemsNamedException e) { + this.logError(this.log, "Unable to set the ratio for external meter."); + } + } + + /** + * Calculate a ratio value. + * + *

+ * Ignore impossible values. + * + * @param valueA value A e.g. 3000A + * @param valueB value B e.g. 5A + * @return ratio value e.g. 600 + */ + protected static Integer calculateRatio(int valueA, int valueB) { + if (valueA <= 0 || valueB <= 0) { + return null; + } + return valueA / valueB; } /** @@ -374,5 +413,4 @@ public ModbusSlaveTable getModbusSlaveTable(AccessMode accessMode) { ModbusSlaveNatureTable.of(GoodWeGridMeter.class, accessMode, 100).build() // ); } - } diff --git a/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImplTest.java b/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImplTest.java index af6028dc629..47b532280ad 100644 --- a/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImplTest.java +++ b/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/GoodWeGridMeterImplTest.java @@ -23,6 +23,8 @@ public class GoodWeGridMeterImplTest { GoodWeGridMeter.ChannelId.METER_CON_INCORRECTLY_L1.id()); private static final ChannelAddress METER_CON_REVERSE_L1 = new ChannelAddress(METER_ID, GoodWeGridMeter.ChannelId.METER_CON_REVERSE_L1.id()); + private static final ChannelAddress EXTERNAL_METER_RATIO = new ChannelAddress(METER_ID, + GoodWeGridMeter.ChannelId.EXTERNAL_METER_RATIO.id()); @Test public void test() throws Exception { @@ -34,6 +36,9 @@ public void test() throws Exception { .activate(MyConfig.create() // .setId(METER_ID) // .setModbusId(MODBUS_ID) // + .setGoodWeMeterCategory(GoodWeGridMeterCategory.SMART_METER) // + .setExternalMeterRatioValueA(0) // + .setExternalMeterRatioValueB(0) // .build()) // .next(new TestCase() // .onBeforeProcessImage(() -> sut.convertMeterConnectStatus(null)) @@ -88,4 +93,57 @@ public void testMeterConnectStateConverter() throws Exception { assert noResult == 0x000; } + + @Test + public void testExternalMeterRatio() throws Exception { + new ComponentTest(new GoodWeGridMeterImpl()) // + .addReference("cm", new DummyConfigurationAdmin()) // + .addReference("setModbus", new DummyModbusBridge(MODBUS_ID)) // + .activate(MyConfig.create() // + .setId(METER_ID) // + .setModbusId(MODBUS_ID) // + .setGoodWeMeterCategory(GoodWeGridMeterCategory.COMMERCIAL_METER) // + .setExternalMeterRatioValueA(3000) // + .setExternalMeterRatioValueB(5) // + .build()) // + .next(new TestCase() // + .output(EXTERNAL_METER_RATIO, 600)); + + new ComponentTest(new GoodWeGridMeterImpl()) // + .addReference("cm", new DummyConfigurationAdmin()) // + .addReference("setModbus", new DummyModbusBridge(MODBUS_ID)) // + .activate(MyConfig.create() // + .setId(METER_ID) // + .setModbusId(MODBUS_ID) // + .setGoodWeMeterCategory(GoodWeGridMeterCategory.COMMERCIAL_METER) // + .setExternalMeterRatioValueA(500) // + .setExternalMeterRatioValueB(5) // + .build()) // + .next(new TestCase() // + .output(EXTERNAL_METER_RATIO, 100)); + + new ComponentTest(new GoodWeGridMeterImpl()) // + .addReference("cm", new DummyConfigurationAdmin()) // + .addReference("setModbus", new DummyModbusBridge(MODBUS_ID)) // + .activate(MyConfig.create() // + .setId(METER_ID) // + .setModbusId(MODBUS_ID) // + .setGoodWeMeterCategory(GoodWeGridMeterCategory.SMART_METER) // + .setExternalMeterRatioValueA(3000) // + .setExternalMeterRatioValueB(5) // + .build()) // + .next(new TestCase() // + .output(EXTERNAL_METER_RATIO, null)); + } + + @Test + public void testCalculateRatio() { + + assertEquals(600, (int) GoodWeGridMeterImpl.calculateRatio(3000, 5)); + assertEquals(100, (int) GoodWeGridMeterImpl.calculateRatio(500, 5)); + assertEquals(null, GoodWeGridMeterImpl.calculateRatio(-5, 5)); + assertEquals(null, GoodWeGridMeterImpl.calculateRatio(3000, 0)); + assertEquals(null, GoodWeGridMeterImpl.calculateRatio(500, -5)); + } + } diff --git a/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/MyConfig.java b/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/MyConfig.java index ab916579d22..67256c4dc57 100644 --- a/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/MyConfig.java +++ b/io.openems.edge.goodwe/test/io/openems/edge/goodwe/gridmeter/MyConfig.java @@ -10,6 +10,9 @@ public static class Builder { private String id; private int modbusUnitId; private String modbusId; + private GoodWeGridMeterCategory goodWeMeterCategory; + private int externalMeterRatioValueA; + private int externalMeterRatioValueB; private Builder() { } @@ -29,6 +32,21 @@ protected Builder setModbusUnitId(int modbusUnitId) { return this; } + protected Builder setGoodWeMeterCategory(GoodWeGridMeterCategory goodWeMeterCategory) { + this.goodWeMeterCategory = goodWeMeterCategory; + return this; + } + + protected Builder setExternalMeterRatioValueA(int externalMeterRatioValueA) { + this.externalMeterRatioValueA = externalMeterRatioValueA; + return this; + } + + protected Builder setExternalMeterRatioValueB(int externalMeterRatioValueB) { + this.externalMeterRatioValueB = externalMeterRatioValueB; + return this; + } + protected MyConfig build() { return new MyConfig(this); } @@ -65,4 +83,19 @@ public String Modbus_target() { return ConfigUtils.generateReferenceTargetFilter(this.id(), this.modbus_id()); } + @Override + public GoodWeGridMeterCategory goodWeMeterCategory() { + return this.builder.goodWeMeterCategory; + } + + @Override + public int externalMeterRatioValueA() { + return this.builder.externalMeterRatioValueA; + } + + @Override + public int externalMeterRatioValueB() { + return this.builder.externalMeterRatioValueB; + } + } \ No newline at end of file diff --git a/io.openems.edge.io.gpio/.classpath b/io.openems.edge.io.gpio/.classpath new file mode 100644 index 00000000000..bbfbdbe40e7 --- /dev/null +++ b/io.openems.edge.io.gpio/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/io.openems.edge.io.gpio/.gitignore b/io.openems.edge.io.gpio/.gitignore new file mode 100644 index 00000000000..c2b941a96de --- /dev/null +++ b/io.openems.edge.io.gpio/.gitignore @@ -0,0 +1,2 @@ +/bin_test/ +/generated/ diff --git a/io.openems.edge.io.gpio/.project b/io.openems.edge.io.gpio/.project new file mode 100644 index 00000000000..f32cce94f00 --- /dev/null +++ b/io.openems.edge.io.gpio/.project @@ -0,0 +1,23 @@ + + + io.openems.edge.io.gpio + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + diff --git a/io.openems.edge.io.gpio/.settings/org.eclipse.core.resources.prefs b/io.openems.edge.io.gpio/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..99f26c0203a --- /dev/null +++ b/io.openems.edge.io.gpio/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/io.openems.edge.io.gpio/bnd.bnd b/io.openems.edge.io.gpio/bnd.bnd new file mode 100644 index 00000000000..b905e4a7177 --- /dev/null +++ b/io.openems.edge.io.gpio/bnd.bnd @@ -0,0 +1,13 @@ +Bundle-Name: OpenEMS Edge IO GPIO +Bundle-Vendor: FENECON GmbH +Bundle-License: https://opensource.org/licenses/EPL-2.0 +Bundle-Version: 1.0.0.${tstamp} + +-buildpath: \ + ${buildpath},\ + io.openems.common,\ + io.openems.edge.common,\ + io.openems.edge.io.api,\ + +-testpath: \ + ${testpath} diff --git a/io.openems.edge.io.gpio/readme.adoc b/io.openems.edge.io.gpio/readme.adoc new file mode 100644 index 00000000000..b2465925da4 --- /dev/null +++ b/io.openems.edge.io.gpio/readme.adoc @@ -0,0 +1,12 @@ += GPIO (General Purpose Input/Output) + +This bundle implements GPIO (General Purpose Input/Output) ports using LinuxFS communication. +Tested mainly on Raspberry Pi based devices. + +== ModBerry X500 CM4 + +The module supports GPIOs of all ModBerry X500 CM4 models. ModBerry is based on the Raspberry Pi Compute Module 4. + +The pin out description is available in the datasheet: https://modberry.techbase.eu/wp-content/uploads/2020/11/ModBerry_500CM4_EN.pdf + +https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.io.gpio[Source Code icon:github[]] \ No newline at end of file diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/Config.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/Config.java new file mode 100644 index 00000000000..1d813ab3fab --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/Config.java @@ -0,0 +1,29 @@ +package io.openems.edge.io.gpio; + +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; + +import io.openems.edge.io.gpio.hardware.HardwareType; + +@ObjectClassDefinition(// + name = "IO GPIO", // + description = "General purpose Input/Output provider for digital IOs") +public @interface Config { + + @AttributeDefinition(name = "Component-ID", description = "Unique ID of this Component") + String id() default "io0"; + + @AttributeDefinition(name = "Alias", description = "Human-readable name of this Component; defaults to Component-ID") + String alias() default ""; + + @AttributeDefinition(name = "Is enabled?", description = "Is this Component enabled?") + boolean enabled() default true; + + @AttributeDefinition(name = "GPIO Path", description = "Path to the GPIOs on the filesystem.") + String gpioPath() default "/sys/class"; + + @AttributeDefinition(name = "Hardware Type", description = "The hardware type in use.") + HardwareType hardwareType() default HardwareType.MODBERRY_X500_M40804_WB; + + String webconsole_configurationFactory_nameHint() default "IO GPIO [{id}]"; +} \ No newline at end of file diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpio.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpio.java new file mode 100644 index 00000000000..3222fa3670e --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpio.java @@ -0,0 +1,21 @@ +package io.openems.edge.io.gpio; + +import io.openems.edge.common.channel.Doc; +import io.openems.edge.common.component.OpenemsComponent; + +public interface IoGpio extends OpenemsComponent { + + public enum ChannelId implements io.openems.edge.common.channel.ChannelId { + ; + private final Doc doc; + + private ChannelId(Doc doc) { + this.doc = doc; + } + + @Override + public Doc doc() { + return this.doc; + } + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpioImpl.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpioImpl.java new file mode 100644 index 00000000000..cab83d3d7ef --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/IoGpioImpl.java @@ -0,0 +1,125 @@ +package io.openems.edge.io.gpio; + +import java.util.stream.Collectors; + +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.ServiceScope; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; +import org.osgi.service.event.propertytypes.EventTopics; +import org.osgi.service.metatype.annotations.Designate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.common.channel.BooleanReadChannel; +import io.openems.edge.common.channel.BooleanWriteChannel; +import io.openems.edge.common.component.AbstractOpenemsComponent; +import io.openems.edge.common.component.OpenemsComponent; +import io.openems.edge.common.event.EdgeEventConstants; +import io.openems.edge.io.api.DigitalInput; +import io.openems.edge.io.api.DigitalOutput; +import io.openems.edge.io.gpio.hardware.HardwarePlatform; + +@Designate(ocd = Config.class, factory = true) +@Component(// + name = "IO.Gpio", // + immediate = true, // + configurationPolicy = ConfigurationPolicy.REQUIRE, // + scope = ServiceScope.SINGLETON // +) +@EventTopics({ // + EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE, // +}) +public class IoGpioImpl extends AbstractOpenemsComponent + implements IoGpio, OpenemsComponent, EventHandler, DigitalInput, DigitalOutput { + + private final Logger log = LoggerFactory.getLogger(IoGpioImpl.class); + + private HardwarePlatform hardwarePlatform; + + public IoGpioImpl() { + super(// + OpenemsComponent.ChannelId.values(), // + IoGpio.ChannelId.values() // + ); + } + + @Activate + private void activate(ComponentContext context, Config config) throws OpenemsException { + super.activate(context, config.id(), config.alias(), config.enabled()); + + // Initialize Hardware + this.hardwarePlatform = config.hardwareType().createInstance(config.gpioPath()); + var channelIds = this.hardwarePlatform.getAllChannelIds(); + this.hardwarePlatform.createPinObjects(channelIds); + this.addChannels(channelIds.toArray(io.openems.edge.common.channel.ChannelId[]::new)); + } + + @Deactivate + protected void deactivate() { + super.deactivate(); + } + + @Override + public String debugLog() { + final var readChannelIds = this.hardwarePlatform.getReadChannelIds(); + final var writeChannelIds = this.hardwarePlatform.getWriteChannelIds(); + return new StringBuilder()// + .append("IO Read[")// + .append(readChannelIds.stream()// + .map(t -> this.hardwarePlatform.getGpioValueByChannelId(t).map(v -> v ? "x" : "-").orElse("?")) + .collect(Collectors.joining()))// + .append("]Write[")// + .append(writeChannelIds.stream()// + .map(t -> this.hardwarePlatform.getGpioValueByChannelId(t).map(v -> v ? "x" : "-").orElse("?")) + .collect(Collectors.joining()))// + .append("]")// + .toString(); + } + + @Override + public void handleEvent(Event event) { + if (!this.isEnabled()) { + return; + } + switch (event.getTopic()) { + case EdgeEventConstants.TOPIC_CYCLE_AFTER_PROCESS_IMAGE -> { + for (var channelId : this.hardwarePlatform.getReadChannelIds()) { + final var nextChannelValue = this.hardwarePlatform.getGpioValueByChannelId(channelId); + this.channel(channelId).setNextValue(nextChannelValue); + } + + for (var channelId : this.hardwarePlatform.getWriteChannelIds()) { + BooleanWriteChannel writeChannel = this.channel(channelId); + final var nextValue = writeChannel.getNextWriteValueAndReset(); + try { + this.hardwarePlatform.setGpio(channelId, nextValue.orElse(false)); + } catch (OpenemsException e) { + this.log.error("Error while setting GPIO " + channelId.name()); + } + } + } + } + } + + @Override + public BooleanWriteChannel[] digitalOutputChannels() { + var writeChannels = this.hardwarePlatform.getWriteChannelIds(); + return writeChannels.stream() // + .map((t -> this.channel(t))) // + .toArray(BooleanWriteChannel[]::new); + } + + @Override + public BooleanReadChannel[] digitalInputChannels() { + var readChannels = this.hardwarePlatform.getReadChannelIds(); + return readChannels.stream() // + .map((t -> this.channel(t))) // + .toArray(BooleanReadChannel[]::new); + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/AbstractGpioChannel.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/AbstractGpioChannel.java new file mode 100644 index 00000000000..a051bec7786 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/AbstractGpioChannel.java @@ -0,0 +1,49 @@ +package io.openems.edge.io.gpio.api; + +import static io.openems.edge.common.type.TypeUtils.assertNull; + +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.common.channel.Doc; + +public abstract class AbstractGpioChannel implements ChannelId { + + /** + * The GPIO number of the hardware entity. + */ + public final int gpio; + + /** + * The human readable name of the GPIO pin. + * + *

+ * NOTE: Channel names should written in UPPER_CASE format because OpenEMS + * converts the names to UpperCamelCase format. Be aware that the channel + * 'DIGITAL_INPUT_1' will be converted to 'DigitalInput1' + * + * @param gpio number of the GPIO pin on the device. + * @param name human readable name of the GPIO pin. + */ + private final String name; + + /** + * The Channel-Doc. + */ + private final Doc doc; + + protected AbstractGpioChannel(int gpio, String name, Doc doc) throws IllegalArgumentException { + assertNull("Channel name for GPIO [" + gpio + "]", name); + this.gpio = gpio; + this.name = name; + this.doc = doc; + } + + @Override + public final String name() { + return this.name; + } + + @Override + public final Doc doc() { + return this.doc; + } +} \ No newline at end of file diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalIn.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalIn.java new file mode 100644 index 00000000000..94d71d011f3 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalIn.java @@ -0,0 +1,15 @@ +package io.openems.edge.io.gpio.api; + +import java.util.Optional; + +public interface DigitalIn { + + /** + * Gets the value of the digital input. + * + * @return true if the input is high, otherwise false. Undefined on + * error/unknown. + */ + Optional getValue(); + +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalOut.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalOut.java new file mode 100644 index 00000000000..eae0d5751d7 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/DigitalOut.java @@ -0,0 +1,15 @@ +package io.openems.edge.io.gpio.api; + +import io.openems.common.exceptions.OpenemsException; + +public interface DigitalOut extends DigitalIn { + + /** + * Sets the value of the GPIO according to the input parameter. + * + * @param value sets the GPIO to high if value is true, otherwise sets it to + * low. + * @throws OpenemsException exception if setting the value is not successful. + */ + public void setValue(boolean value) throws OpenemsException; +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/ReadChannelId.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/ReadChannelId.java new file mode 100644 index 00000000000..c9d8656cd7b --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/ReadChannelId.java @@ -0,0 +1,16 @@ +package io.openems.edge.io.gpio.api; + +import io.openems.common.channel.AccessMode; +import io.openems.common.channel.PersistencePriority; +import io.openems.common.types.OpenemsType; +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.common.channel.Doc; + +public class ReadChannelId extends AbstractGpioChannel implements ChannelId { + + public ReadChannelId(int gpio, String name) { + super(gpio, name, Doc.of(OpenemsType.BOOLEAN)// + .accessMode(AccessMode.READ_ONLY)// + .persistencePriority(PersistencePriority.HIGH)); + } +} \ No newline at end of file diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/WriteChannelId.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/WriteChannelId.java new file mode 100644 index 00000000000..24fc5fb52a9 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/api/WriteChannelId.java @@ -0,0 +1,16 @@ +package io.openems.edge.io.gpio.api; + +import io.openems.common.channel.AccessMode; +import io.openems.common.channel.PersistencePriority; +import io.openems.common.types.OpenemsType; +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.common.channel.Doc; + +public class WriteChannelId extends AbstractGpioChannel implements ChannelId { + + public WriteChannelId(int gpio, String name) { + super(gpio, name, Doc.of(OpenemsType.BOOLEAN)// + .accessMode(AccessMode.READ_WRITE)// + .persistencePriority(PersistencePriority.HIGH)); + } +} \ No newline at end of file diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwarePlatform.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwarePlatform.java new file mode 100644 index 00000000000..baa8ea5e92d --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwarePlatform.java @@ -0,0 +1,73 @@ +package io.openems.edge.io.gpio.hardware; + +import java.util.List; +import java.util.Optional; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.io.gpio.api.AbstractGpioChannel; +import io.openems.edge.io.gpio.api.ReadChannelId; +import io.openems.edge.io.gpio.api.WriteChannelId; + +public interface HardwarePlatform { + + /** + * Gets all channels of the hardware. + * + * @return List of hardware pins. + */ + public List getAllChannelIds(); + + /** + * Gets the write channel IDs of the platform. + * + * @return List of WriteChannelIds. + */ + public default List getWriteChannelIds() { + return this.getAllChannelIds().stream()// + .filter(WriteChannelId.class::isInstance)// + .map(WriteChannelId.class::cast)// + .toList(); + } + + /** + * Gets all read channels of the hardware device. These include digital and + * analog inputs. + * + * @return List of hardware pins. + */ + public default List getReadChannelIds() { + return this.getAllChannelIds().stream()// + .filter(ReadChannelId.class::isInstance)// + .map(ReadChannelId.class::cast)// + .toList(); + } + + /** + * Creates pin objects based on hardware enum description. + * + * @param channels List of hardware description values. Each of the will be + * exported as a channel. + */ + public void createPinObjects(List channels); + + /** + * Gets the value of a GPIO pin based on the given channel. + * + * @param channelId hardware channel to be queried. + * @return the value of the digital IO. true if high, otherwise + * false. + */ + public Optional getGpioValueByChannelId(AbstractGpioChannel channelId); + + /** + * Sets the value of a GPIO based. + * + * @param channelId hardware channel to set + * @param value the new requested value. In case of digital IOs, the value + * should be boolean. + * @throws OpenemsException thrown in the case if there is an OS/Hardware + * failure. + */ + public void setGpio(WriteChannelId channelId, boolean value) throws OpenemsException; +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwareType.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwareType.java new file mode 100644 index 00000000000..38f6ff1ac8d --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/HardwareType.java @@ -0,0 +1,24 @@ +package io.openems.edge.io.gpio.hardware; + +import io.openems.edge.io.gpio.linuxfs.HardwareFactory; + +public enum HardwareType { + MODBERRY_X500_M40804_MAX, // + MODBERRY_X500_M40804_WB, // + MODBERRY_X500_M40804_W; + + /** + * Create a {@link HardwarePlatform} for this {@link HardwareType}. + * + * @param gpioPath the GPIO path + * @return the {@link HardwarePlatform} + */ + public HardwarePlatform createInstance(String gpioPath) { + var factory = new HardwareFactory(gpioPath); + return switch (this) { + case MODBERRY_X500_M40804_MAX -> new ModberryX500M40804Max(factory); + case MODBERRY_X500_M40804_WB -> new ModberryX500M40804Wb(factory); + case MODBERRY_X500_M40804_W -> new ModberryX500M40804W(factory); + }; + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModBerryX500CM4.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModBerryX500CM4.java new file mode 100644 index 00000000000..b728a960c74 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModBerryX500CM4.java @@ -0,0 +1,45 @@ +package io.openems.edge.io.gpio.hardware; + +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.io.gpio.api.AbstractGpioChannel; +import io.openems.edge.io.gpio.api.WriteChannelId; +import io.openems.edge.io.gpio.linuxfs.Gpio; +import io.openems.edge.io.gpio.linuxfs.HardwareFactory; +import io.openems.edge.io.gpio.linuxfs.LinuxFsDigitalOut; + +public abstract class ModBerryX500CM4 implements HardwarePlatform { + + private HardwareFactory context; + private HashMap ios; + + public ModBerryX500CM4(HardwareFactory context) { + this.context = context; + this.ios = new HashMap<>(); + } + + @Override + public void createPinObjects(List channelIds) { + this.getReadChannelIds().stream().forEach(readChannel -> { + this.ios.put(readChannel.gpio, this.context.fabricateIn(readChannel.gpio)); + }); + + this.getWriteChannelIds().stream().forEach(writeChannel -> { + this.ios.put(writeChannel.gpio, this.context.fabricateOut(writeChannel.gpio)); + }); + } + + @Override + public Optional getGpioValueByChannelId(AbstractGpioChannel channelId) { + return this.ios.get(channelId.gpio).getValue(); + } + + @Override + public void setGpio(WriteChannelId channelId, boolean value) throws OpenemsException { + ((LinuxFsDigitalOut) this.ios.get(channelId.gpio)).setValue(value); + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Max.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Max.java new file mode 100644 index 00000000000..73ce422752c --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Max.java @@ -0,0 +1,35 @@ +package io.openems.edge.io.gpio.hardware; + +import java.util.List; + +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.io.gpio.api.ReadChannelId; +import io.openems.edge.io.gpio.api.WriteChannelId; +import io.openems.edge.io.gpio.linuxfs.HardwareFactory; + +public final class ModberryX500M40804Max extends ModBerryX500CM4 { + + private final List channelIds = List.of(// + new ReadChannelId(18, "DIGITAL_INPUT_1"), // + new ReadChannelId(19, "DIGITAL_INPUT_2"), // + new ReadChannelId(20, "DIGITAL_INPUT_3"), // + new ReadChannelId(21, "DIGITAL_INPUT_4"), // + new WriteChannelId(22, "DIGITAL_OUTPUT_1"), // + new WriteChannelId(23, "DIGITAL_OUTPUT_2"), // + new WriteChannelId(24, "DIGITAL_OUTPUT_3"), // + new WriteChannelId(25, "DIGITAL_OUTPUT_4"), // + new ReadChannelId(500, "DIGITAL_INPUT_OUTPUT_1"), // + new ReadChannelId(501, "DIGITAL_INPUT_OUTPUT_2"), // + new ReadChannelId(502, "DIGITAL_INPUT_OUTPUT_3"), // + new ReadChannelId(503, "DIGITAL_INPUT_OUTPUT_4") // + ); + + public ModberryX500M40804Max(HardwareFactory context) { + super(context); + } + + @Override + public List getAllChannelIds() { + return this.channelIds; + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804W.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804W.java new file mode 100644 index 00000000000..ed2b2148797 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804W.java @@ -0,0 +1,31 @@ +package io.openems.edge.io.gpio.hardware; + +import java.util.List; + +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.io.gpio.api.ReadChannelId; +import io.openems.edge.io.gpio.api.WriteChannelId; +import io.openems.edge.io.gpio.linuxfs.HardwareFactory; + +public final class ModberryX500M40804W extends ModBerryX500CM4 { + + private final List channels = List.of(// + new ReadChannelId(18, "DIGITAL_INPUT_1"), // + new ReadChannelId(19, "DIGITAL_INPUT_2"), // + new ReadChannelId(20, "DIGITAL_INPUT_3"), // + new ReadChannelId(21, "DIGITAL_INPUT_4"), // + new WriteChannelId(22, "DIGITAL_OUTPUT_1"), // + new WriteChannelId(23, "DIGITAL_OUTPUT_2"), // + new WriteChannelId(24, "DIGITAL_OUTPUT_3"), // + new WriteChannelId(25, "DIGITAL_OUTPUT_4") // + ); + + public ModberryX500M40804W(HardwareFactory context) { + super(context); + } + + @Override + public List getAllChannelIds() { + return this.channels; + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Wb.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Wb.java new file mode 100644 index 00000000000..1ecf02dd6c6 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/hardware/ModberryX500M40804Wb.java @@ -0,0 +1,31 @@ +package io.openems.edge.io.gpio.hardware; + +import java.util.List; + +import io.openems.edge.common.channel.ChannelId; +import io.openems.edge.io.gpio.api.ReadChannelId; +import io.openems.edge.io.gpio.api.WriteChannelId; +import io.openems.edge.io.gpio.linuxfs.HardwareFactory; + +public final class ModberryX500M40804Wb extends ModBerryX500CM4 { + + private final List channels = List.of(// + new ReadChannelId(18, "DIGITAL_INPUT_1"), // + new ReadChannelId(19, "DIGITAL_INPUT_2"), // + new ReadChannelId(20, "DIGITAL_INPUT_3"), // + new ReadChannelId(21, "DIGITAL_INPUT_4"), // + new WriteChannelId(22, "DIGITAL_OUTPUT_1"), // + new WriteChannelId(23, "DIGITAL_OUTPUT_2"), // + new WriteChannelId(24, "DIGITAL_OUTPUT_3"), // + new WriteChannelId(25, "DIGITAL_OUTPUT_4") // + ); + + public ModberryX500M40804Wb(HardwareFactory context) { + super(context); + } + + @Override + public List getAllChannelIds() { + return this.channels; + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Direction.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Direction.java new file mode 100644 index 00000000000..cb64bbdb6b9 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Direction.java @@ -0,0 +1,6 @@ +package io.openems.edge.io.gpio.linuxfs; + +public enum Direction { + IN, // + OUT +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Gpio.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Gpio.java new file mode 100644 index 00000000000..7391d7c4a91 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/Gpio.java @@ -0,0 +1,118 @@ +package io.openems.edge.io.gpio.linuxfs; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.openems.common.exceptions.OpenemsException; + +public class Gpio implements AutoCloseable { + + private final Logger log = LoggerFactory.getLogger(Gpio.class); + private final int pinNumber; + private final String basePath; + + public Gpio(int pinNumber, Direction dir, String basePath) { + this.basePath = basePath; + this.pinNumber = pinNumber; + try { + this.exportPin(basePath, pinNumber); + this.setDirection(dir); + + } catch (OpenemsException e) { + this.log.error(e.getMessage()); + } + } + + protected void writeValue(String value) throws OpenemsException { + this.writeFile(this.valuePath(this.pinNumber), value); + } + + /** + * Gets the value of the GPIO pin. + * + * @return a value of true/false if reading the value was successful, otherwise + * empty. + */ + public Optional getValue() { + try { + return Optional.of(this.readFile() == '1'); + } catch (OpenemsException ex) { + return Optional.empty(); + } + } + + @Override + public void close() throws Exception { + this.writeFile(this.unexportPath(this.basePath), Integer.toString(this.pinNumber)); + } + + private String devicePath(int num) { + return this.basePath + String.format("/gpio%d", num); + } + + private String directionPath(int num) { + return this.devicePath(num) + "/direction"; + } + + private String valuePath(int num) { + return this.devicePath(num) + "/value"; + } + + private String exportPath(String basePath) { + return basePath + "/export"; + } + + private String unexportPath(String basePath) { + return basePath + "/unexport"; + } + + private void setDirection(Direction dir) throws OpenemsException { + if (dir.equals(Direction.IN)) { + this.writeFile(this.directionPath(this.pinNumber), "in"); + } else { + this.writeFile(this.directionPath(this.pinNumber), "out"); + } + } + + private void exportPin(String basePath, int pinNumber) throws OpenemsException { + this.writeFile(this.exportPath(basePath), Integer.toString(pinNumber)); + } + + private synchronized void writeFile(String filename, String value) throws OpenemsException { + try (var fos = new FileOutputStream(filename)) { + fos.write(value.getBytes()); + } catch (IOException ex) { + var msg = ex.getMessage(); + if (msg.contains("Permission denied")) { + throw new OpenemsException("Not able to export GPIO pin [" + this.pinNumber + "]: permission denied."); + } else if (msg.contains("busy")) { + throw new OpenemsException("Skipping write to GPIO pin [" + this.pinNumber + "]: device is busy."); + } else { + throw new OpenemsException("Unkown error writing GPIO file: " + msg); + } + } + } + + private synchronized int readFile() throws OpenemsException { + try (var fis = new FileInputStream(this.valuePath(this.pinNumber))) { + return fis.read(); + } catch (IOException ex) { + var msg = ex.getMessage(); + if (msg.contains("Permission denied")) { + throw new OpenemsException("Permission denied to GPIO file: " + msg); + } else { + throw new OpenemsException("Could not read from GPIO file: " + msg); + } + } + } + + @Override + public String toString() { + return "GPIO" + this.pinNumber; + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/HardwareFactory.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/HardwareFactory.java new file mode 100644 index 00000000000..81111282303 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/HardwareFactory.java @@ -0,0 +1,30 @@ +package io.openems.edge.io.gpio.linuxfs; + +public class HardwareFactory { + + private final String basePath; + + public HardwareFactory(String gpioPath) { + this.basePath = gpioPath + "/gpio"; + } + + /** + * Creates a digital input with Linux file system driver. + * + * @param gpio the number of the GPIO on the device. + * @return a java object that represents the digital input. + */ + public LinuxFsDigitalIn fabricateIn(int gpio) { + return new LinuxFsDigitalIn(gpio, this.basePath); + } + + /** + * Creates a digital output with Linux file system driver. + * + * @param gpio the number of the GPIO on the device. + * @return a java object that represents the digital output. + */ + public LinuxFsDigitalOut fabricateOut(int gpio) { + return new LinuxFsDigitalOut(gpio, this.basePath); + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalIn.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalIn.java new file mode 100644 index 00000000000..59a98cd0162 --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalIn.java @@ -0,0 +1,15 @@ +package io.openems.edge.io.gpio.linuxfs; + +import io.openems.edge.io.gpio.api.DigitalIn; + +public class LinuxFsDigitalIn extends Gpio implements DigitalIn { + + public LinuxFsDigitalIn(int pinNumber, String basePath) { + super(pinNumber, Direction.IN, basePath); + } + + @Override + public String toString() { + return super.toString() + ": " + this.getValue().map(t -> t ? "on" : "off").orElse("invalid"); + } +} diff --git a/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalOut.java b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalOut.java new file mode 100644 index 00000000000..f92a75a34ef --- /dev/null +++ b/io.openems.edge.io.gpio/src/io/openems/edge/io/gpio/linuxfs/LinuxFsDigitalOut.java @@ -0,0 +1,26 @@ +package io.openems.edge.io.gpio.linuxfs; + +import io.openems.common.exceptions.OpenemsException; +import io.openems.edge.io.gpio.api.DigitalOut; + +public class LinuxFsDigitalOut extends Gpio implements DigitalOut { + + public LinuxFsDigitalOut(int pinNumber, String basePath) { + super(pinNumber, Direction.OUT, basePath); + } + + /** + * Sets the value of the output. + * + * @param value true if the output should be low, false otherwise. + * @throws OpenemsException if the value could not be written to the device. + */ + public void setValue(boolean value) throws OpenemsException { + this.writeValue(value ? "1" : "0"); + } + + @Override + public String toString() { + return this.getValue().map(t -> t ? "on" : "off").orElse("error"); + } +} diff --git a/io.openems.edge.io.gpio/test/.gitignore b/io.openems.edge.io.gpio/test/.gitignore new file mode 100644 index 00000000000..e69de29bb2d diff --git a/io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/ModberryCM4Test.java b/io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/ModberryCM4Test.java new file mode 100644 index 00000000000..113c39f7c6a --- /dev/null +++ b/io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/ModberryCM4Test.java @@ -0,0 +1,265 @@ +package io.openems.edge.io.gpio; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import io.openems.common.types.ChannelAddress; +import io.openems.edge.common.channel.WriteChannel; +import io.openems.edge.common.test.AbstractComponentTest.TestCase; +import io.openems.edge.common.test.ComponentTest; +import io.openems.edge.common.test.DummyComponentManager; +import io.openems.edge.io.api.DigitalInput; +import io.openems.edge.io.api.DigitalOutput; +import io.openems.edge.io.gpio.api.AbstractGpioChannel; +import io.openems.edge.io.gpio.api.ReadChannelId; +import io.openems.edge.io.gpio.api.WriteChannelId; +import io.openems.edge.io.gpio.hardware.HardwareType; + +public class ModberryCM4Test { + + private File root; + + private static final String ID = "io0"; + + private static final List CHANNEL_IDS = List.of(// + new ReadChannelId(18, "DigitalInput1"), // + new ReadChannelId(19, "DigitalInput2"), // + new ReadChannelId(20, "DigitalInput3"), // + new ReadChannelId(21, "DigitalInput4"), // + new WriteChannelId(22, "DigitalOutput1"), // + new WriteChannelId(23, "DigitalOutput2"), // + new WriteChannelId(24, "DigitalOutput3"), // + new WriteChannelId(25, "DigitalOutput4") // + ); + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Before + public void setUp() throws IOException { + try { + this.folder.create(); + this.root = this.folder.getRoot(); + new File(this.root.getAbsolutePath() + "/gpio").mkdir(); + this.fileWithDirectoryAssurance(this.root.getAbsolutePath() + File.separator + "gpio", "export"); + } catch (IOException ioe) { + throw new IOException("error creating temporary test file in " + this.getClass().getSimpleName()); + } + for (var channelId : CHANNEL_IDS) { + this.createDirectoryForGpio(this.folder, channelId.gpio); + } + } + + private File fileWithDirectoryAssurance(String directory, String filename) { + File dir = new File(directory); + if (!dir.exists()) { + dir.mkdirs(); + } + return new File(directory + File.separatorChar + filename); + } + + private void createDirectoryForGpio(TemporaryFolder root, int gpioNumber) throws IOException { + var rootPath = root.getRoot().getAbsolutePath(); + var basePath = rootPath + File.separatorChar + "gpio" + File.separatorChar + "gpio" + gpioNumber; + var valueFile = this.fileWithDirectoryAssurance(basePath, "value"); + Files.writeString(valueFile.toPath(), "0", Charset.defaultCharset()); + this.fileWithDirectoryAssurance(basePath, "direction"); + } + + private String readGpioFile(File root, int gpioNumber) throws IOException { + var path = Path.of(String.join(File.separator, root.getAbsolutePath(), "gpio", "gpio" + gpioNumber, "value")); + return Files.readString(path); + } + + private void setGpioFile(File root, int gpioNumber, int value) throws IOException { + var path = Path.of(String.join(File.separator, root.getAbsolutePath(), "gpio", "gpio" + gpioNumber, "value")); + Files.writeString(path, String.valueOf(value)); + } + + @Test + public void testChannelIdsAreCorrect() throws Exception { + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + IoGpio modberryComponent = new IoGpioImpl(); + new ComponentTest(modberryComponent).activate(config); + assertNotNull(modberryComponent.channel("DigitalInput1")); + } + + @Test + public void testComponentLoadsSucesfully() throws Exception { + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + new ComponentTest(new IoGpioImpl()) // + .activate(config); + } + + @Test + public void testInputValuesAreDefault() throws Exception { + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + new ComponentTest(new IoGpioImpl()) // + .activate(config) // + .next(new TestCase("Default input values are false") // + .output(new ChannelAddress(ID, "DigitalInput1"), false) // + .output(new ChannelAddress(ID, "DigitalInput2"), false) // + .output(new ChannelAddress(ID, "DigitalInput3"), false) // + .output(new ChannelAddress(ID, "DigitalInput4"), false) // + ); + } + + @Test + public void testChangeOutputWrittenToFs() throws Exception { + assertEquals(this.readGpioFile(this.root, 22), "0"); + assertEquals(this.readGpioFile(this.root, 23), "0"); + assertEquals(this.readGpioFile(this.root, 24), "0"); + assertEquals(this.readGpioFile(this.root, 25), "0"); + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + new ComponentTest(new IoGpioImpl()) // + .activate(config) // + .next(new TestCase("Write values are written to fs.") // + .input(new ChannelAddress(ID, "DigitalOutput1"), true) // + .input(new ChannelAddress(ID, "DigitalOutput2"), true) // + .input(new ChannelAddress(ID, "DigitalOutput3"), true) // + .input(new ChannelAddress(ID, "DigitalOutput4"), true) // + ); + assertEquals(this.readGpioFile(this.root, 22), "1"); + assertEquals(this.readGpioFile(this.root, 23), "1"); + assertEquals(this.readGpioFile(this.root, 24), "1"); + assertEquals(this.readGpioFile(this.root, 25), "1"); + } + + @Test + public void testChangeInputIsDetected() throws Exception { + assertEquals(this.readGpioFile(this.root, 18), "0"); + assertEquals(this.readGpioFile(this.root, 19), "0"); + assertEquals(this.readGpioFile(this.root, 20), "0"); + assertEquals(this.readGpioFile(this.root, 21), "0"); + + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + + new ComponentTest(new IoGpioImpl()) // + .activate(config) // + .next(new TestCase("Read values are detected by the component.") // + .output(new ChannelAddress(ID, "DigitalInput1"), false) // + .output(new ChannelAddress(ID, "DigitalInput2"), false) // + .output(new ChannelAddress(ID, "DigitalInput3"), false) // + .output(new ChannelAddress(ID, "DigitalInput4"), false) // + ); + + this.setGpioFile(this.root, 18, 1); + this.setGpioFile(this.root, 19, 1); + this.setGpioFile(this.root, 20, 1); + this.setGpioFile(this.root, 21, 1); + + assertEquals(this.readGpioFile(this.root, 18), "1"); + assertEquals(this.readGpioFile(this.root, 19), "1"); + assertEquals(this.readGpioFile(this.root, 20), "1"); + assertEquals(this.readGpioFile(this.root, 21), "1"); + + new ComponentTest(new IoGpioImpl()) // + .activate(config) // + .next(new TestCase("Read values are detected by the component.") // + .output(new ChannelAddress(ID, "DigitalInput1"), true) // + .output(new ChannelAddress(ID, "DigitalInput2"), true) // + .output(new ChannelAddress(ID, "DigitalInput3"), true) // + .output(new ChannelAddress(ID, "DigitalInput4"), true) // + ); + } + + @Test + public void testJavaApi() throws Exception { + this.setGpioFile(this.root, 22, 0); + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + var componentManager = new DummyComponentManager(); + var componentTest = new ComponentTest(new IoGpioImpl()).activate(config); + componentManager.addComponent(componentTest.getSut()); + + // Get get component channel value as java reference + WriteChannel writeChannel = componentManager.getChannel(new ChannelAddress(ID, "DigitalOutput1")); + assertFalse(writeChannel.value().isDefined()); + writeChannel.setNextValue(true); + } + + @Test + public void testInterfaceDigitalOutputChannels() throws Exception { + this.setGpioFile(this.root, 22, 0); + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + var componentManager = new DummyComponentManager(); + var componentTest = new ComponentTest(new IoGpioImpl()) // + .activate(config); + componentManager.addComponent(componentTest.getSut()); + var comp = componentTest.getSut(); + assertTrue(((DigitalOutput) comp).digitalOutputChannels().length == 4); + } + + @Test + public void testInterfaceDigitalInputChannels() throws Exception { + this.setGpioFile(this.root, 22, 0); + var config = MyConfig.create() // + .setId(ID) // + .setAlias(ID) // + .setEnabled(true) // + .setGpioPath(this.folder.getRoot().getAbsolutePath()) // + .setHardwareType(HardwareType.MODBERRY_X500_M40804_W) // + .build(); + var componentManager = new DummyComponentManager(); + var componentTest = new ComponentTest(new IoGpioImpl()) // + .activate(config); + componentManager.addComponent(componentTest.getSut()); + var comp = componentTest.getSut(); + assertTrue(((DigitalInput) comp).digitalInputChannels().length == 4); + } +} diff --git a/io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/MyConfig.java b/io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/MyConfig.java new file mode 100644 index 00000000000..3405d81766c --- /dev/null +++ b/io.openems.edge.io.gpio/test/io/openems/edge/io/gpio/MyConfig.java @@ -0,0 +1,89 @@ +package io.openems.edge.io.gpio; + +import io.openems.common.test.AbstractComponentConfig; +import io.openems.edge.io.gpio.hardware.HardwareType; + +@SuppressWarnings("all") +public class MyConfig extends AbstractComponentConfig implements Config { + + protected static class Builder { + private String id; + private String alias; + private boolean enabled; + private String gpioPath; + private HardwareType hardwareType; + + private Builder() { + } + + public Builder setId(String id) { + this.id = id; + return this; + } + + public Builder setAlias(String alias) { + this.alias = alias; + return this; + } + + public Builder setEnabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + public Builder setGpioPath(String gpioPath) { + this.gpioPath = gpioPath; + return this; + } + + public Builder setHardwareType(HardwareType hardwareType) { + this.hardwareType = hardwareType; + return this; + } + + public MyConfig build() { + return new MyConfig(this); + } + } + + /** + * Create a Config builder. + * + * @return a {@link Builder} + */ + public static Builder create() { + return new Builder(); + } + + private final Builder builder; + + private MyConfig(Builder builder) { + super(Config.class, builder.id); + this.builder = builder; + } + + @Override + public String id() { + return this.builder.id; + } + + @Override + public String alias() { + return this.builder.alias; + } + + @Override + public boolean enabled() { + return this.builder.enabled; + } + + @Override + public String gpioPath() { + return this.builder.gpioPath; + } + + @Override + public HardwareType hardwareType() { + return this.builder.hardwareType; + } +} \ No newline at end of file diff --git a/io.openems.edge.timedata.rrd4j/.gitignore b/io.openems.edge.timedata.rrd4j/.gitignore index a2790f9ffe9..c2b941a96de 100644 --- a/io.openems.edge.timedata.rrd4j/.gitignore +++ b/io.openems.edge.timedata.rrd4j/.gitignore @@ -1,3 +1,2 @@ /bin_test/ /generated/ -rrd4j diff --git a/io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/RecordWorkerFactory.java b/io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/RecordWorkerFactory.java new file mode 100644 index 00000000000..06f000c6bfa --- /dev/null +++ b/io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/RecordWorkerFactory.java @@ -0,0 +1,36 @@ +package io.openems.edge.timedata.rrd4j; + +import org.osgi.service.component.ComponentServiceObjects; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; + +@Component(service = RecordWorkerFactory.class) +public class RecordWorkerFactory { + + @Reference + private ComponentServiceObjects cso; + + /** + * Returns a new {@link RecordWorker} service object. + * + * @return the created {@link RecordWorker} object + * @see #unget(RecordWorker) + */ + public RecordWorker get() { + return this.cso.getService(); + } + + /** + * Releases the {@link RecordWorker} service object. + * + * @param service a {@link RecordWorker} provided by this factory + * @see #get() + */ + public void unget(RecordWorker service) { + if (service == null) { + return; + } + this.cso.ungetService(service); + } + +} diff --git a/io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/TimedataRrd4jImpl.java b/io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/TimedataRrd4jImpl.java index 5d23c3343a4..e1d6898bcfd 100644 --- a/io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/TimedataRrd4jImpl.java +++ b/io.openems.edge.timedata.rrd4j/src/io/openems/edge/timedata/rrd4j/TimedataRrd4jImpl.java @@ -12,7 +12,6 @@ import org.osgi.service.component.annotations.ConfigurationPolicy; import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceScope; import org.osgi.service.event.Event; import org.osgi.service.event.EventHandler; import org.osgi.service.event.propertytypes.EventTopics; @@ -41,7 +40,8 @@ public final class TimedataRrd4jImpl extends AbstractOpenemsComponent implements TimedataRrd4j, Timedata, OpenemsComponent, EventHandler { - @Reference(scope = ReferenceScope.PROTOTYPE_REQUIRED) + @Reference + private RecordWorkerFactory workerFactory; private RecordWorker worker; @Reference @@ -62,6 +62,7 @@ private void activate(ComponentContext context, Config config) throws Exception super.activate(context, config.id(), config.alias(), config.enabled()); this.debugMode = config.debugMode(); + this.worker = this.workerFactory.get(); this.worker.setConfig(new RecordWorker.Config(// this.id(), // config.isReadOnly(), // @@ -78,6 +79,8 @@ private void activate(ComponentContext context, Config config) throws Exception @Deactivate protected void deactivate() { super.deactivate(); + this.workerFactory.unget(this.worker); + this.worker = null; } @Override diff --git a/io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/DummyRecordWorkerFactory.java b/io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/DummyRecordWorkerFactory.java new file mode 100644 index 00000000000..b4af1e2e5a3 --- /dev/null +++ b/io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/DummyRecordWorkerFactory.java @@ -0,0 +1,52 @@ +package io.openems.edge.timedata.rrd4j; + +import java.lang.reflect.InvocationTargetException; + +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.ComponentServiceObjects; + +import io.openems.common.utils.ReflectionUtils; +import io.openems.edge.common.component.ComponentManager; + +public class DummyRecordWorkerFactory extends RecordWorkerFactory { + + public DummyRecordWorkerFactory(ComponentManager componentManager) + throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + super(); + ReflectionUtils.setAttribute(RecordWorkerFactory.class, this, "cso", + new DummyRecordWorkerCso(componentManager)); + } + + private static class DummyRecordWorkerCso implements ComponentServiceObjects { + + private final ComponentManager componentManager; + + public DummyRecordWorkerCso(ComponentManager componentManager) { + super(); + this.componentManager = componentManager; + } + + @Override + public RecordWorker getService() { + final var worker = new RecordWorker(); + try { + ReflectionUtils.setAttribute(RecordWorker.class, worker, "componentManager", this.componentManager); + } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + return worker; + } + + @Override + public void ungetService(RecordWorker service) { + // empty for tests + } + + @Override + public ServiceReference getServiceReference() { + // empty for tests + return null; + } + } + +} diff --git a/io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/TimedataRrd4jImplTest.java b/io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/TimedataRrd4jImplTest.java index 7b6aa5e0312..52a2c9d45ee 100644 --- a/io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/TimedataRrd4jImplTest.java +++ b/io.openems.edge.timedata.rrd4j/test/io/openems/edge/timedata/rrd4j/TimedataRrd4jImplTest.java @@ -16,7 +16,6 @@ import org.rrd4j.core.RrdMemoryBackendFactory; import io.openems.common.channel.PersistencePriority; -import io.openems.common.utils.ReflectionUtils; import io.openems.edge.common.test.AbstractComponentTest.TestCase; import io.openems.edge.common.test.ComponentTest; import io.openems.edge.common.test.DummyComponentManager; @@ -28,10 +27,8 @@ public class TimedataRrd4jImplTest { @Test public void test() throws Exception { final var componentManager = new DummyComponentManager(); - final var worker = new RecordWorker(); - ReflectionUtils.setAttribute(RecordWorker.class, worker, "componentManager", componentManager); new ComponentTest(new TimedataRrd4jImpl()) // - .addReference("worker", worker) // + .addReference("workerFactory", new DummyRecordWorkerFactory(componentManager)) // .addReference("readHandler", new Rrd4jReadHandler()) // .activate(MyConfig.create() // .setId(COMPONENT_ID) // diff --git a/tools/build-debian-package.sh b/tools/build-debian-package.sh index 594c7ad505a..9582af59322 100755 --- a/tools/build-debian-package.sh +++ b/tools/build-debian-package.sh @@ -1,8 +1,8 @@ -#!/bin/bash +#!/bin/bash -e # # Creates a Debian package for OpenEMS Edge + UI -set -e +OUTPUT=$( realpath ${1:-.} ) DEBIAN_UI_LOCATION=tools/debian/usr/share/openems/www DEBIAN_EDGE_LOCATION=tools/debian/usr/lib/openems/ @@ -37,8 +37,9 @@ print_header() { echo "#" echo "# Building Debian Package" echo "#" - echo "# Theme: ${THEME}" - echo "# Version: ${VERSION}" + echo -e "# Theme:\t${THEME}" + echo -e "# Version:\t${VERSION}" + echo -e "# Destination:\t${OUTPUT}" echo "#" } @@ -75,13 +76,13 @@ prepare_deb_template() { build_deb() { cd tools - dpkg-deb -Zxz --build "debian" "../${DEB_FILE}" + dpkg-deb -Zxz --build "debian" "${OUTPUT}/${DEB_FILE}" echo "## Built ${DEB_FILE}" cd .. } create_version_file() { - echo $VERSION > $VERSION_FILE + echo $VERSION > "${OUTPUT}/${VERSION_FILE}" } clean_deb_template() { diff --git a/tools/common.sh b/tools/common.sh index 3b1d74d0c41..f3f937fa62a 100644 --- a/tools/common.sh +++ b/tools/common.sh @@ -1,3 +1,5 @@ +#!/bin/bash -e +# # Provides commonly used functions and variables common_initialize_environment() { @@ -12,7 +14,7 @@ common_initialize_environment() { PACKAGE_NAME="openems-edge" VERSION_STRING="" VERSION="$(cd ui && node -p "require('./package.json').version" && cd ..)" - tmp_version=$(echo $VERSION | cut -d'-' -f1) + local tmp_version=$(echo $VERSION | cut -d'-' -f1) VERSION_MAJOR=$(echo $tmp_version | cut -d'.' -f1) VERSION_MINOR=$(echo $tmp_version | cut -d'.' -f2) VERSION_PATCH=$(echo $tmp_version | cut -d'.' -f3) @@ -21,21 +23,18 @@ common_initialize_environment() { common_build_snapshot_version() { if [[ "$VERSION" == *"-SNAPSHOT" ]]; then - echo "1" # Replace unwanted characters with '.', compliant with Debian version # Ref: https://unix.stackexchange.com/a/23673 VERSION_DEV_BRANCH="$(git branch --show-current)" - echo "2" VERSION_DEV_COMMIT="" - if [[ $(git diff --stat) != '' ]]; then + git diff --exit-code --quiet; + if [ $? -ne 0 ]; then VERSION_DEV_COMMIT="dirty" else VERSION_DEV_COMMIT="$(git rev-parse --short HEAD)" fi - echo "3" VERSION_DEV_BUILD_TIME=$(date "+%Y%m%d.%H%M") # Compliant with https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version - echo "4" VERSION_STRING="$(echo $VERSION_DEV_BRANCH | tr -cs 'a-zA-Z0-9\n' '.').${VERSION_DEV_BUILD_TIME}.${VERSION_DEV_COMMIT}" VERSION="${VERSION/-SNAPSHOT/"-${VERSION_STRING}"}" fi @@ -45,22 +44,22 @@ common_build_snapshot_version() { common_update_version_in_code() { echo "# Update version in Code" echo "## Update $SRC_OPENEMS_CONSTANTS" - sed --in-place "s/\(VERSION_MAJOR = \)\([0-9]\+\);$/\1$VERSION_MAJOR;/" $SRC_OPENEMS_CONSTANTS - sed --in-place "s/\(VERSION_MINOR = \)\([0-9]\+\);$/\1$VERSION_MINOR;/" $SRC_OPENEMS_CONSTANTS - sed --in-place "s/\(VERSION_PATCH = \)\([0-9]\+\);$/\1$VERSION_PATCH;/" $SRC_OPENEMS_CONSTANTS - sed --in-place "s/\(VERSION_STRING = \)\"\(.*\)\";$/\1\"$VERSION_STRING\";/" $SRC_OPENEMS_CONSTANTS - sed --in-place "s/\(VERSION_DEV_BRANCH = \)\"\(.*\)\";$/\1\"${VERSION_DEV_BRANCH/\//\\/}\";/" $SRC_OPENEMS_CONSTANTS - sed --in-place "s/\(VERSION_DEV_COMMIT = \)\"\(.*\)\";$/\1\"$VERSION_DEV_COMMIT\";/" $SRC_OPENEMS_CONSTANTS - sed --in-place "s/\(VERSION_DEV_BUILD_TIME = \)\"\(.*\)\";$/\1\"$VERSION_DEV_BUILD_TIME\";/" $SRC_OPENEMS_CONSTANTS + sed --in-place "s#\(VERSION_MAJOR = \)\([0-9]\+\);#\1$VERSION_MAJOR;#" $SRC_OPENEMS_CONSTANTS + sed --in-place "s#\(VERSION_MINOR = \)\([0-9]\+\);#\1$VERSION_MINOR;#" $SRC_OPENEMS_CONSTANTS + sed --in-place "s#\(VERSION_PATCH = \)\([0-9]\+\);#\1$VERSION_PATCH;#" $SRC_OPENEMS_CONSTANTS + sed --in-place "s#\(VERSION_STRING = \)\"\(.*\)\";#\1\"$VERSION_STRING\";#" $SRC_OPENEMS_CONSTANTS + sed --in-place "s#\(VERSION_DEV_BRANCH = \)\"\(.*\)\";#\1\"${VERSION_DEV_BRANCH}\";#" $SRC_OPENEMS_CONSTANTS + sed --in-place "s#\(VERSION_DEV_COMMIT = \)\"\(.*\)\";#\1\"$VERSION_DEV_COMMIT\";#" $SRC_OPENEMS_CONSTANTS + sed --in-place "s#\(VERSION_DEV_BUILD_TIME = \)\"\(.*\)\";#\1\"$VERSION_DEV_BUILD_TIME\";#" $SRC_OPENEMS_CONSTANTS echo "## Update $SRC_PACKAGE_JSON" - sed --in-place "s/^\( \"version\": \"\).*\(\".*$\)/\1$VERSION\2/" $SRC_PACKAGE_JSON + sed --in-place "s#^\( \"version\": \"\).*\(\".*$\)#\1$VERSION\2#" $SRC_PACKAGE_JSON echo "## Update $SRC_PACKAGE_LOCK_JSON" - sed --in-place "s/^\( \"version\": \"\).*\(\".*$\)/\1$VERSION\2/" $SRC_PACKAGE_LOCK_JSON + sed --in-place "s#^\( \"version\": \"\).*\(\".*$\)#\1$VERSION\2#" $SRC_PACKAGE_LOCK_JSON echo "## Update $SRC_CHANGELOG_CONSTANTS" - sed --in-place "s/\(UI_VERSION = \"\).*\(\";\)$/\1$VERSION\2/" $SRC_CHANGELOG_CONSTANTS + sed --in-place "s#\(UI_VERSION = \"\).*\(\";\)#\1$VERSION\2#" $SRC_CHANGELOG_CONSTANTS } # Build OpenEMS Edge and UI in parallel @@ -101,4 +100,18 @@ common_build_ui() { echo "## Refresh node_modules cache" mv -f "ui/node_modules" "${NODE_MODULES_CACHE}" fi +} + +common_save_environment() { + local file=${1:-build.environment} + echo " + export VERSION=\"$VERSION\" + export VERSION_MAJOR=\"$VERSION_MAJOR\" + export VERSION_MINOR=\"$VERSION_MINOR\" + export VERSION_PATCH=\"$VERSION_PATCH\" + export VERSION_STRING=\"$VERSION_STRING\" + export VERSION_DEV_BRANCH=\"$VERSION_DEV_BRANCH\" + export VERSION_DEV_COMMIT=\"$VERSION_DEV_COMMIT\" + export VERSION_DEV_BUILD_TIME=\"$VERSION_DEV_BUILD_TIME\" + " | tee $file } \ No newline at end of file diff --git a/ui/package-lock.json b/ui/package-lock.json index cdd8bbf30a6..0d37eea46e4 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -10,6 +10,7 @@ "license": "AGPL-3.0", "dependencies": { "@angular/animations": "~15.2.9", + "@angular/cdk": "~15.2.9", "@angular/common": "~15.2.9", "@angular/core": "~15.2.9", "@angular/forms": "~15.2.9", @@ -23,13 +24,15 @@ "@ngx-formly/schematics": "^6.1.7", "@ngx-translate/core": "^14.0.0", "angular-mydatepicker": "^0.11.5", - "chart.js": "^2.9.4", + "chart.js": "^4.4.0", + "chartjs-adapter-date-fns": "^3.0.0", + "chartjs-plugin-zoom": "^2.0.1", "classlist.js": "^1.1.20150312", "compare-versions": "^6.1.0", "d3": "^7.8.5", "date-fns": "^2.30.0", "file-saver-es": "^2.0.5", - "ng2-charts": "^2.4.3", + "ng2-charts": "4.1.1", "ngx-cookie-service": "^15.0.0", "ngx-spinner": "^15.0.1", "roboto-fontface": "^0.10.0", @@ -75,16 +78,18 @@ }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/@ampproject/remapping": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -95,8 +100,9 @@ }, "node_modules/@angular-devkit/architect": { "version": "0.1502.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.9.tgz", + "integrity": "sha512-CFn+LbtYeLG7WqO+BBSjogl764StHpwgfJnNAXQ/3UouUktZ92z4lxhUm0PwIPb5k0lILsf81ubcS1vzwoXEEg==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/core": "15.2.9", "rxjs": "6.6.7" @@ -109,8 +115,9 @@ }, "node_modules/@angular-devkit/build-angular": { "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-15.2.9.tgz", + "integrity": "sha512-djOo2Q22zLrxPccSbINz93hD+pES/nNPoze4Ys/0IdtMlLmxO/YGsA+FG5eNeNAf2jK/JRoNydaYOh7XpGoCzA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "2.2.0", "@angular-devkit/architect": "0.1502.9", @@ -216,6 +223,7 @@ } } }, +<<<<<<< HEAD "node_modules/@angular-devkit/build-angular/node_modules/brace-expansion": { "version": "2.0.1", "dev": true, @@ -239,10 +247,22 @@ "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" +======= + "node_modules/@angular-devkit/build-angular/node_modules/esbuild": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.8.tgz", + "integrity": "sha512-g24ybC3fWhZddZK6R3uD2iF/RIPnRpwJAqLov6ouX3hMbY4+tKolP0VMF3zuIYCaXun+yHwS5IPQ91N2BT191g==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "bin": { + "esbuild": "bin/esbuild" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">=12" }, +<<<<<<< HEAD "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -305,6 +325,44 @@ "version": "0.1502.9", "dev": true, "license": "MIT", +======= + "optionalDependencies": { + "@esbuild/android-arm": "0.17.8", + "@esbuild/android-arm64": "0.17.8", + "@esbuild/android-x64": "0.17.8", + "@esbuild/darwin-arm64": "0.17.8", + "@esbuild/darwin-x64": "0.17.8", + "@esbuild/freebsd-arm64": "0.17.8", + "@esbuild/freebsd-x64": "0.17.8", + "@esbuild/linux-arm": "0.17.8", + "@esbuild/linux-arm64": "0.17.8", + "@esbuild/linux-ia32": "0.17.8", + "@esbuild/linux-loong64": "0.17.8", + "@esbuild/linux-mips64el": "0.17.8", + "@esbuild/linux-ppc64": "0.17.8", + "@esbuild/linux-riscv64": "0.17.8", + "@esbuild/linux-s390x": "0.17.8", + "@esbuild/linux-x64": "0.17.8", + "@esbuild/netbsd-x64": "0.17.8", + "@esbuild/openbsd-x64": "0.17.8", + "@esbuild/sunos-x64": "0.17.8", + "@esbuild/win32-arm64": "0.17.8", + "@esbuild/win32-ia32": "0.17.8", + "@esbuild/win32-x64": "0.17.8" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1502.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1502.9.tgz", + "integrity": "sha512-VzMXoZjrbL1XlcSegqpZCBDbVvKFGPs3cKp4bXDD5ht95jcCyJPk5FA/wrh0pGGwbOF8ae/XOWFcPRzctC35iA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@angular-devkit/architect": "0.1502.9", "rxjs": "6.6.7" @@ -321,8 +379,12 @@ }, "node_modules/@angular-devkit/core": { "version": "15.2.9", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.9.tgz", + "integrity": "sha512-6u44YJ9tEG2hiWITL1rwA9yP6ot4a3cyN/UOMRkYSa/XO2Gz5/dM3U74E2kwg+P1NcxLXffBWl0rz8/Y/lSZyQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", @@ -344,6 +406,7 @@ } } }, +<<<<<<< HEAD "node_modules/@angular-devkit/schematics": { "version": "15.2.9", "dev": true, @@ -363,19 +426,68 @@ }, "node_modules/@angular-devkit/schematics/node_modules/magic-string": { "version": "0.29.0", +======= + "node_modules/@angular-devkit/core/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/core/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/@angular-devkit/schematics": { + "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.9.tgz", + "integrity": "sha512-o08nE8sTpfq/Fknrr1rzBsM8vY36BDox+8dOo9Zc/KqcVPwDy94YKRzHb+xxVaU9jy1VYeCjy63mkyELy7Z3zQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "@jridgewell/sourcemap-codec": "^1.4.13" }, "engines": { "node": ">=12" } }, +======= + "@angular-devkit/core": "15.2.9", + "jsonc-parser": "3.2.0", + "magic-string": "0.29.0", + "ora": "5.4.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@angular-eslint/builder": { "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-15.2.1.tgz", + "integrity": "sha512-7x2DANebLRl997Mj4DhZrnz5+vnSjavGGveJ0mBuU7CEsL0ZYLftdRqL0e0HtU3ksseS7xpchD6OM08nkNgySw==", "dev": true, - "license": "MIT", "peerDependencies": { "eslint": "^7.20.0 || ^8.0.0", "typescript": "*" @@ -383,13 +495,15 @@ }, "node_modules/@angular-eslint/bundled-angular-compiler": { "version": "15.2.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-15.2.1.tgz", + "integrity": "sha512-LO7Am8eVCr7oh6a0VmKSL7K03CnQEQhFO7Wt/YtbfYOxVjrbwmYLwJn+wZPOT7A02t/BttOD/WXuDrOWtSMQ/Q==", + "dev": true }, "node_modules/@angular-eslint/eslint-plugin": { "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-15.2.1.tgz", + "integrity": "sha512-OM7b1kS4E4CkXjkaWN+lEzawh4VxY6l7FO1Cuk4s7iv3/YpZG3rJxIZBqnFLTixwrBuqw8y4FNBzF3eDgmFAUw==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/utils": "15.2.1", "@typescript-eslint/utils": "5.48.2" @@ -401,8 +515,9 @@ }, "node_modules/@angular-eslint/eslint-plugin-template": { "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-15.2.1.tgz", + "integrity": "sha512-IeiSLk6YxapFdH2z5o/O3R7VwtBd2T6fWmhLFPwDYMDknrwegnOjwswCdBplOccpUp0wqlCeGUx7LTsuzwaz7w==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/bundled-angular-compiler": "15.2.1", "@angular-eslint/utils": "15.2.1", @@ -418,8 +533,9 @@ }, "node_modules/@angular-eslint/template-parser": { "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-15.2.1.tgz", + "integrity": "sha512-ViCi79gC2aKJecmYLkOT+QlT5WMRNXeYz0Dr9Pr8qXzIbY0oAWE7nOT5jkXwQ9oUk+ybtGCWHma5JVJWVJsIog==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/bundled-angular-compiler": "15.2.1", "eslint-scope": "^7.0.0" @@ -431,8 +547,12 @@ }, "node_modules/@angular-eslint/template-parser/node_modules/eslint-scope": { "version": "7.2.2", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -446,16 +566,18 @@ }, "node_modules/@angular-eslint/template-parser/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/@angular-eslint/utils": { "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-15.2.1.tgz", + "integrity": "sha512-++FneAJHxJqcSu0igVN6uOkSoHxlzgLoMBswuovYJy3UKwm33/T6WFku8++753Ca/JucIoR1gdUfO7SoSspMDg==", "dev": true, - "license": "MIT", "dependencies": { "@angular-eslint/bundled-angular-compiler": "15.2.1", "@typescript-eslint/utils": "5.48.2" @@ -467,7 +589,8 @@ }, "node_modules/@angular/animations": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-15.2.9.tgz", + "integrity": "sha512-GQujLhI0cQFcl4Q8y0oSYKSRnW23GIeSL+Arl4eFufziJ9hGAAQNuesaNs/7i+9UlTHDMkPH3kd5ScXuYYz6wg==", "dependencies": { "tslib": "^2.3.0" }, @@ -478,10 +601,51 @@ "@angular/core": "15.2.9" } }, + "node_modules/@angular/cdk": { + "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-15.2.9.tgz", + "integrity": "sha512-koaM07N1AIQ5oHU27l0/FoQSSoYAwlAYwVZ4Di3bYrJsTBNCN2Xsby7wI8gZxdepMnV4Fe9si382BDBov+oO4Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^15.0.0 || ^16.0.0", + "@angular/core": "^15.0.0 || ^16.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cdk/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "optional": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@angular/cdk/node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "optional": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/@angular/cli": { "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-15.2.9.tgz", + "integrity": "sha512-mI6hkGyIJDKd8MRiBl3p5chsUhgnluwmpsq3g1FFPw+wv+eXsPYgCiHqXS/OsK+shFxii9XMxoZQO28bJ4NAOQ==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1502.9", "@angular-devkit/core": "15.2.9", @@ -511,9 +675,36 @@ "yarn": ">= 1.13.0" } }, +<<<<<<< HEAD +======= + "node_modules/@angular/cli/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/@angular/cli/node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@angular/common": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-15.2.9.tgz", + "integrity": "sha512-LM9/UHG2dRrOzlu2KovrFwWIziFMjRxHzSP3Igw6Symw/wIl0kXGq8Fn6RpFP78zmLqnv+IQOoRiby9MCXsI4g==", "dependencies": { "tslib": "^2.3.0" }, @@ -527,7 +718,8 @@ }, "node_modules/@angular/compiler": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-15.2.9.tgz", + "integrity": "sha512-MoKugbjk+E0wRBj12uvIyDLELlVLonnqjA2+XiF+7FxALIeyds3/qQeEoMmYIqAbN3NnTT5pV92RxWwG4tHFwA==", "dependencies": { "tslib": "^2.3.0" }, @@ -545,8 +737,9 @@ }, "node_modules/@angular/compiler-cli": { "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-15.2.9.tgz", + "integrity": "sha512-zsbI8G2xHOeYWI0hjFzrI//ZhZV9il/uQW5dAimfwJp06KZDeXZ3PdwY9JQslf6F+saLwOObxy6QMrIVvfjy9w==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "7.19.3", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -582,8 +775,9 @@ }, "node_modules/@angular/compiler-cli/node_modules/@babel/core": { "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", @@ -611,8 +805,9 @@ }, "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { "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.js" } @@ -817,8 +1012,9 @@ }, "node_modules/@angular/compiler-cli/node_modules/magic-string": { "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" }, @@ -833,7 +1029,8 @@ }, "node_modules/@angular/core": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-15.2.9.tgz", + "integrity": "sha512-w46Z1yUXCQfKV7XfnamOoLA2VD0MVUUYVrUjO73mHSskDXSXxfZAEHO9kfUS71Cj35PvhP3mbkqWscpea2WeYg==", "dependencies": { "tslib": "^2.3.0" }, @@ -847,7 +1044,8 @@ }, "node_modules/@angular/forms": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-15.2.9.tgz", + "integrity": "sha512-sk0pC2EFi2Ohg5J0q0NYptbT+2WOkoiERSMYA39ncDvlSZBWsNlxpkbGUSck7NIxjK2QfcVN1ldGbHlZTFvtqg==", "dependencies": { "tslib": "^2.3.0" }, @@ -863,15 +1061,17 @@ }, "node_modules/@angular/language-service": { "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-15.2.9.tgz", + "integrity": "sha512-B7lP4q/eHge2lZezOXS96EYzVf4stMCWfOnz7+pUUi0HbF+A5QCV65SWQddS/M+NM2jj8N2L/j+6UCH8lJjTQA==", "dev": true, - "license": "MIT", "engines": { "node": "^14.20.0 || ^16.13.0 || >=18.10.0" } }, "node_modules/@angular/platform-browser": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-15.2.9.tgz", + "integrity": "sha512-ufCHeSX+U6d43YOMkn3igwfqtlozoCXADcbyfUEG8m2y9XASobqmCKvdSk/zfl62oyiA8msntWBJVBE2l4xKXg==", "dependencies": { "tslib": "^2.3.0" }, @@ -891,7 +1091,8 @@ }, "node_modules/@angular/platform-browser-dynamic": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-15.2.9.tgz", + "integrity": "sha512-ZIYDM6MShblb8OyV1m4+18lJJ2LCeICmeg2uSbpFYptYBSOClrTiYOOFVDJvn7HLvNzljLs16XPrgyaYVqNpcw==", "dependencies": { "tslib": "^2.3.0" }, @@ -907,7 +1108,8 @@ }, "node_modules/@angular/router": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-15.2.9.tgz", + "integrity": "sha512-UCbh5DLSDhybv0xKYT7kGQMfOVdyhHIHOZz5EYVebbhste6S+W1LE57vTHq7QtxJsyKBa/WSkaUkCLXD6ntCAg==", "dependencies": { "tslib": "^2.3.0" }, @@ -923,7 +1125,8 @@ }, "node_modules/@angular/service-worker": { "version": "15.2.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-15.2.9.tgz", + "integrity": "sha512-qM/lcrjaxIfpKj174mMWedtGfLNgLl5m7p9mPNODFjqp5lQj3fTTS643ix5Pr0onwbvbNbXu4g67/WXJqap0eA==", "dependencies": { "tslib": "^2.3.0" }, @@ -940,13 +1143,20 @@ }, "node_modules/@assemblyscript/loader": { "version": "0.10.1", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz", + "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", + "dev": true }, "node_modules/@babel/code-frame": { +<<<<<<< HEAD "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", +======= + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, "dependencies": { "@babel/highlight": "^7.23.4", @@ -956,10 +1166,25 @@ "node": ">=6.9.0" } }, +<<<<<<< HEAD "node_modules/@babel/core": { "version": "7.20.12", +======= + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", @@ -1185,8 +1410,9 @@ }, "node_modules/@babel/core/node_modules/semver": { "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.js" } @@ -1198,8 +1424,9 @@ }, "node_modules/@babel/generator": { "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", @@ -1211,8 +1438,12 @@ }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1224,8 +1455,9 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.18.6" }, @@ -1233,11 +1465,18 @@ "node": ">=6.9.0" } }, +<<<<<<< HEAD "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.3", +======= + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", "debug": "^4.1.1", @@ -1290,6 +1529,34 @@ }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/browserslist": { "version": "4.21.10", +======= + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, "funding": [ { @@ -1305,12 +1572,18 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { +<<<<<<< HEAD "caniuse-lite": "^1.0.30001517", "electron-to-chromium": "^1.4.477", "node-releases": "^2.0.13", "update-browserslist-db": "^1.0.11" +======= + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "bin": { "browserslist": "cli.js" @@ -1319,67 +1592,62 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, +<<<<<<< HEAD "node_modules/@babel/helper-define-polyfill-provider/node_modules/lru-cache": { "version": "5.1.1", "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { +======= + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "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.js" } }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.7.tgz", + "integrity": "sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==", "dev": true, "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@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-function-name/node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { "@babel/types": "^7.22.5" @@ -1388,158 +1656,183 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@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-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "engines": { - "node": ">=6.9.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.4.0-0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, - "node_modules/@babel/parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", - "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", + "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" + "semver": "bin/semver.js" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.7", + "node_modules/@babel/helper-define-polyfill-provider/node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/helper-function-name/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.9", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.9" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/helper-wrap-function": { - "version": "7.22.10", +<<<<<<< HEAD +======= + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.10" + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/template": { + "node_modules/@babel/helper-module-imports": { "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@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" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", + "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1547,65 +1840,64 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.15", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "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" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.15", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.15" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@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/plugin-proposal-class-properties/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-replace-supers": { - "version": "7.22.9", + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { @@ -1615,10 +1907,11 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "node_modules/@babel/helper-simple-access": { "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1626,10 +1919,11 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1637,113 +1931,183 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-class-properties/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/@babel/helper-split-export-declaration": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-dynamic-import/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, +<<<<<<< HEAD +======= "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-export-namespace-from/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-json-strings/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", + "node_modules/@babel/helpers": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/helpers/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, - "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { +<<<<<<< HEAD + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.4.tgz", + "integrity": "sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==", +======= + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, +<<<<<<< HEAD +======= + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { "node": ">=6.9.0" @@ -1752,41 +2116,73 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-async-generator-functions/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/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", + "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.9", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-optional-catch-binding/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/helper-wrap-function": { + "version": "7.22.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions/node_modules/@babel/template": { + "version": "7.22.15", "dev": true, "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-private-methods": { + "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1798,18 +2194,26 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-annotate-as-pure": { +<<<<<<< HEAD + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", +======= + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead.", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-create-class-features-plugin": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-create-class-features-plugin": { "version": "7.22.15", "dev": true, "license": "MIT", @@ -1823,6 +2227,11 @@ "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "semver": "^6.3.1" +======= + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-class-static-block": "^7.14.5" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">=6.9.0" @@ -1831,7 +2240,7 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-member-expression-to-functions": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-member-expression-to-functions": { "version": "7.22.15", "dev": true, "license": "MIT", @@ -1842,7 +2251,7 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-optimise-call-expression": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-optimise-call-expression": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -1853,7 +2262,7 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -1861,7 +2270,7 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-replace-supers": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-replace-supers": { "version": "7.22.9", "dev": true, "license": "MIT", @@ -1877,7 +2286,7 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -1888,7 +2297,7 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-split-export-declaration": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", "dev": true, "license": "MIT", @@ -1899,7 +2308,7 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-private-methods/node_modules/semver": { + "node_modules/@babel/plugin-proposal-class-properties/node_modules/semver": { "version": "6.3.1", "dev": true, "license": "ISC", @@ -1907,49 +2316,49 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "node_modules/@babel/plugin-proposal-dynamic-import": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/@babel/helper-annotate-as-pure": { + "node_modules/@babel/plugin-proposal-dynamic-import/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", - "dependencies": { - "@babel/types": "^7.22.5" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-export-namespace-from/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -1957,53 +2366,62 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/regenerate-unicode-properties": { - "version": "10.1.1", + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.", "dev": true, - "license": "MIT", "dependencies": { - "regenerate": "^1.4.2" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/regexpu-core": { - "version": "5.3.2", +<<<<<<< HEAD + "node_modules/@babel/plugin-proposal-json-strings/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", "dev": true, "license": "MIT", +======= + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead.", + "dev": true, "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" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@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-syntax-async-generators/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2011,31 +2429,56 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-properties/node_modules/@babel/helper-plugin-utils": { +<<<<<<< HEAD + "node_modules/@babel/plugin-proposal-numeric-separator/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", +======= + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { "node": ">=6.9.0" @@ -2044,64 +2487,115 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-static-block/node_modules/@babel/helper-plugin-utils": { +<<<<<<< HEAD + "node_modules/@babel/plugin-proposal-optional-catch-binding/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", +======= + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dev": true, + "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" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import/node_modules/@babel/helper-plugin-utils": { +<<<<<<< HEAD + "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", +======= + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", + "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", + "dependencies": { +<<<<<<< HEAD + "@babel/types": "^7.22.5" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", + "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.22.15", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" + "@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" +======= + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.22.15", "dev": true, "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.15" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", + "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/types": "^7.22.5" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-json-strings/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2109,56 +2603,97 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", + "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-replace-supers": { + "version": "7.22.9", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-private-methods/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/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", + "node_modules/@babel/plugin-proposal-private-methods/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-unicode-property-regex/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/plugin-syntax-numeric-separator": { - "version": "7.10.4", + "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@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-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2166,29 +2701,46 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", + "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/regenerate-unicode-properties": { + "version": "10.1.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "regenerate": "^1.4.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=4" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread/node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", + "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/regexpu-core": { + "version": "5.3.2", "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" + }, "engines": { - "node": ">=6.9.0" + "node": ">=4" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", + "node_modules/@babel/plugin-proposal-unicode-property-regex/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -2196,7 +2748,7 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-syntax-async-generators/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2204,18 +2756,19 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-chaining/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-syntax-class-properties/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2223,10 +2776,11 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { + "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -2237,7 +2791,7 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-syntax-class-static-block/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2245,21 +2799,19 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-top-level-await/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-syntax-dynamic-import/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2267,45 +2819,50 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.20.7", + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { +<<<<<<< HEAD + "node_modules/@babel/plugin-syntax-export-namespace-from/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", +======= + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5" }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-module-imports": { - "version": "7.22.15", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-plugin-utils": { + "node_modules/@babel/plugin-syntax-json-strings/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", @@ -2313,49 +2870,575 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.9", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.9" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-wrap-function": { - "version": "7.22.10", + "node_modules/@babel/plugin-syntax-logical-assignment-operators/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.10" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/template": { - "version": "7.22.15", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-optional-chaining": { + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "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-private-property-in-object/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, +<<<<<<< HEAD + "node_modules/@babel/plugin-syntax-top-level-await/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", +======= + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, +<<<<<<< HEAD + "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", +======= + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "dependencies": { +<<<<<<< HEAD + "@babel/types": "^7.22.5" +======= + "@babel/helper-plugin-utils": "^7.22.5" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + }, + "engines": { + "node": ">=6.9.0" + } + }, +<<<<<<< HEAD + "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-module-imports": { + "version": "7.22.15", +======= + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "dependencies": { +<<<<<<< HEAD + "@babel/types": "^7.22.15" +======= + "@babel/helper-plugin-utils": "^7.22.5" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + }, + "engines": { + "node": ">=6.9.0" + } + }, +<<<<<<< HEAD + "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "dev": true, + "license": "MIT", +======= + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "engines": { + "node": ">=6.9.0" + } + }, +<<<<<<< HEAD + "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.9", +======= + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "dependencies": { +<<<<<<< HEAD + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-wrap-function": "^7.22.9" +======= + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties/node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dev": true, + "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_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", + "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, +<<<<<<< HEAD + "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-wrap-function": { + "version": "7.22.10", +======= + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "dependencies": { +<<<<<<< HEAD + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/template": { + "version": "7.22.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.22.15", "dev": true, "license": "MIT", @@ -2363,6 +3446,9 @@ "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" +======= + "@babel/helper-plugin-utils": "^7.22.5" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">=6.9.0" @@ -2371,29 +3457,121 @@ "@babel/core": "^7.0.0-0" } }, +<<<<<<< HEAD "node_modules/@babel/plugin-transform-optional-chaining/node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", "dev": true, "license": "MIT", +======= + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dev": true, + "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" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=6.9.0" } }, +<<<<<<< HEAD "node_modules/@babel/plugin-transform-optional-chaining/node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.22.5", +======= + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" +======= + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/@babel/plugin-transform-runtime": { "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", + "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.19.0", @@ -2428,18 +3606,130 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, +<<<<<<< HEAD +======= + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dev": true, + "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_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@babel/preset-env": { "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.20.1", "@babel/helper-compilation-targets": "^7.20.0", @@ -2524,6 +3814,7 @@ "@babel/core": "^7.0.0-0" } }, +<<<<<<< HEAD "node_modules/@babel/preset-env/node_modules/@babel/compat-data": { "version": "7.22.9", "dev": true, @@ -3310,8 +4601,22 @@ }, "node_modules/@babel/preset-env/node_modules/@babel/preset-modules": { "version": "0.1.6", +======= + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", + "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -3323,6 +4628,7 @@ "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, +<<<<<<< HEAD "node_modules/@babel/preset-env/node_modules/@babel/template": { "version": "7.22.15", "dev": true, @@ -3439,11 +4745,19 @@ "version": "0.8.0", "dev": true, "license": "MIT" +======= + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/@babel/runtime": { "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", "dev": true, - "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -3453,8 +4767,9 @@ }, "node_modules/@babel/template": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/parser": "^7.20.7", @@ -3465,6 +4780,7 @@ } }, "node_modules/@babel/traverse": { +<<<<<<< HEAD "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.4.tgz", "integrity": "sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==", @@ -3472,13 +4788,28 @@ "dependencies": { "@babel/code-frame": "^7.23.4", "@babel/generator": "^7.23.4", +======= + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "@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", +<<<<<<< HEAD "@babel/parser": "^7.23.4", "@babel/types": "^7.23.4", "debug": "^4.1.0", +======= + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "globals": "^11.1.0" }, "engines": { @@ -3486,12 +4817,21 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { +<<<<<<< HEAD "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.4.tgz", "integrity": "sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==", "dev": true, "dependencies": { "@babel/types": "^7.23.4", +======= + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -3527,9 +4867,15 @@ } }, "node_modules/@babel/types": { +<<<<<<< HEAD "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.4.tgz", "integrity": "sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==", +======= + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", @@ -3537,73 +4883,419 @@ "to-fast-properties": "^2.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.39.4", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.39.4.tgz", + "integrity": "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg==", + "dev": true, + "dependencies": { + "comment-parser": "1.3.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, +<<<<<<< HEAD + "node_modules/@esbuild/linux-x64": { +======= + "node_modules/@esbuild/android-arm": { +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.8.tgz", + "integrity": "sha512-0/rb91GYKhrtbeglJXOhAv9RuYimgI8h623TplY2X+vA4EXnk3Zj1fXZreJ0J3OJJu1bwmb0W7g+2cT/d8/l/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.8.tgz", + "integrity": "sha512-oa/N5j6v1svZQs7EIRPqR8f+Bf8g6HBDjD/xHC02radE/NjKHK7oQmtmLxPs1iVwYyvE+Kolo6lbpfEQ9xnhxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.8.tgz", + "integrity": "sha512-bTliMLqD7pTOoPg4zZkXqCDuzIUguEWLpeqkNfC41ODBHwoUgZ2w5JBeYimv4oP6TDVocoYmEhZrCLQTrH89bg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.8.tgz", + "integrity": "sha512-ghAbV3ia2zybEefXRRm7+lx8J/rnupZT0gp9CaGy/3iolEXkJ6LYRq4IpQVI9zR97ID80KJVoUlo3LSeA/sMAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.8.tgz", + "integrity": "sha512-n5WOpyvZ9TIdv2V1K3/iIkkJeKmUpKaCTdun9buhGRWfH//osmUjlv4Z5mmWdPWind/VGcVxTHtLfLCOohsOXw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.8.tgz", + "integrity": "sha512-a/SATTaOhPIPFWvHZDoZYgxaZRVHn0/LX1fHLGfZ6C13JqFUZ3K6SMD6/HCtwOQ8HnsNaEeokdiDSFLuizqv5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.8.tgz", + "integrity": "sha512-xpFJb08dfXr5+rZc4E+ooZmayBW6R3q59daCpKZ/cDU96/kvDM+vkYzNeTJCGd8rtO6fHWMq5Rcv/1cY6p6/0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.8.tgz", + "integrity": "sha512-6Ij8gfuGszcEwZpi5jQIJCVIACLS8Tz2chnEBfYjlmMzVsfqBP1iGmHQPp7JSnZg5xxK9tjCc+pJ2WtAmPRFVA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.8.tgz", + "integrity": "sha512-v3iwDQuDljLTxpsqQDl3fl/yihjPAyOguxuloON9kFHYwopeJEf1BkDXODzYyXEI19gisEsQlG1bM65YqKSIww==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.8.tgz", + "integrity": "sha512-8svILYKhE5XetuFk/B6raFYIyIqydQi+GngEXJgdPdI7OMKUbSd7uzR02wSY4kb53xBrClLkhH4Xs8P61Q2BaA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.8.tgz", + "integrity": "sha512-B6FyMeRJeV0NpyEOYlm5qtQfxbdlgmiGdD+QsipzKfFky0K5HW5Td6dyK3L3ypu1eY4kOmo7wW0o94SBqlqBSA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.8.tgz", + "integrity": "sha512-CCb67RKahNobjm/eeEqeD/oJfJlrWyw29fgiyB6vcgyq97YAf3gCOuP6qMShYSPXgnlZe/i4a8WFHBw6N8bYAA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.8.tgz", + "integrity": "sha512-bytLJOi55y55+mGSdgwZ5qBm0K9WOCh0rx+vavVPx+gqLLhxtSFU0XbeYy/dsAAD6xECGEv4IQeFILaSS2auXw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.8.tgz", + "integrity": "sha512-2YpRyQJmKVBEHSBLa8kBAtbhucaclb6ex4wchfY0Tj3Kg39kpjeJ9vhRU7x4mUpq8ISLXRXH1L0dBYjAeqzZAw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.8.tgz", + "integrity": "sha512-QgbNY/V3IFXvNf11SS6exkpVcX0LJcob+0RWCgV9OiDAmVElnxciHIisoSix9uzYzScPmS6dJFbZULdSAEkQVw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", + "node_modules/@esbuild/linux-x64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.8.tgz", + "integrity": "sha512-mM/9S0SbAFDBc4OPoyP6SEOo5324LpUxdpeIUUSrSTOfhHU9hEfqRngmKgqILqwx/0DVJBzeNW7HmLEWp9vcOA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.1.90" + "node": ">=12" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.8.tgz", + "integrity": "sha512-eKUYcWaWTaYr9zbj8GertdVtlt1DTS1gNBWov+iQfWuWyuu59YN6gSEJvFzC5ESJ4kMcKR0uqWThKUn5o8We6Q==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { "node": ">=12" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.8.tgz", + "integrity": "sha512-Vc9J4dXOboDyMXKD0eCeW0SIeEzr8K9oTHJU+Ci1mZc5njPfhKAqkRt3B/fUNU7dP+mRyralPu8QUkiaQn7iIg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.0.0" + "node": ">=12" } }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.8.tgz", + "integrity": "sha512-0xvOTNuPXI7ft1LYUgiaXtpCEjp90RuBBYovdd2lqAFxje4sEucurg30M1WIm03+3jxByd3mfo+VUmPtRSVuOw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.8.tgz", + "integrity": "sha512-G0JQwUI5WdEFEnYNKzklxtBheCPkuDdu1YrtRrjuQv30WsYbkkoixKxLLv8qhJmNI+ATEWquZe/N0d0rpr55Mg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=10.0.0" + "node": ">=12" } }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.39.4", + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.8.tgz", + "integrity": "sha512-Fqy63515xl20OHGFykjJsMnoIWS+38fqfg88ClvPXyDbLtgXal2DTlhb1TfTX34qWi3u4I7Cq563QcHpqgLx8w==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "MIT", - "dependencies": { - "comment-parser": "1.3.1", - "esquery": "^1.5.0", - "jsdoc-type-pratt-parser": "~4.0.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=16" + "node": ">=12" } }, - "node_modules/@esbuild/linux-x64": { + "node_modules/@esbuild/win32-x64": { "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.8.tgz", + "integrity": "sha512-1iuezdyDNngPnz8rLRDO2C/ZZ/emJLb72OsZeqQ6gL6Avko/XCXZw+NuxBSNhBAP13Hie418V7VMt9et1FMvpg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -3614,8 +5306,9 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -3627,17 +5320,23 @@ } }, "node_modules/@eslint-community/regexpp": { +<<<<<<< HEAD "version": "4.8.0", +======= + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -3658,8 +5357,9 @@ }, "node_modules/@eslint/eslintrc/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3673,13 +5373,23 @@ }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", +<<<<<<< HEAD "dev": true, "license": "Python-2.0" }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.21.0", +======= + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -3692,19 +5402,35 @@ }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.0", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } +<<<<<<< HEAD +======= + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3713,20 +5439,35 @@ } }, "node_modules/@eslint/js": { +<<<<<<< HEAD "version": "8.52.0", +======= + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -3740,8 +5481,9 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -3750,9 +5492,22 @@ "url": "https://github.com/sponsors/nzakas" } }, +<<<<<<< HEAD "node_modules/@ionic/angular": { "version": "6.7.5", "license": "MIT", +======= + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@ionic/angular": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-6.7.4.tgz", + "integrity": "sha512-E41OEAXZFe7rhtseD0R+cEsE2qOxMBGeCGwNNdnoiWtU35+I60YM0M1NaXUd8iiSCUX6v794CETQQeazBxSORg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@ionic/core": "6.7.5", "ionicons": "^6.1.3", @@ -3769,8 +5524,9 @@ }, "node_modules/@ionic/angular-toolkit": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-7.0.0.tgz", + "integrity": "sha512-9nVeGuGRO3sUYSVzcHmddPd9+C+XDW2BpRSxCqMK1MKLlfnnpVMP1TTf/IDQhBj+koHwBAQBj6voBSsFUzTKBg==", "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/core": "^14.0.0", "@angular-devkit/schematics": "^14.0.0", @@ -3778,9 +5534,16 @@ } }, "node_modules/@ionic/angular-toolkit/node_modules/@angular-devkit/core": { +<<<<<<< HEAD "version": "14.2.12", "dev": true, "license": "MIT", +======= + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.13.tgz", + "integrity": "sha512-aIefeZcbjghQg/V6U9CTLtyB5fXDJ63KwYqVYkWP+i0XriS5A9puFgq2u/OVsWxAfYvqpDqp5AdQ0g0bi3CAsA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "ajv": "8.11.0", "ajv-formats": "2.1.1", @@ -3803,11 +5566,20 @@ } }, "node_modules/@ionic/angular-toolkit/node_modules/@angular-devkit/schematics": { +<<<<<<< HEAD "version": "14.2.12", "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": "14.2.12", +======= + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.13.tgz", + "integrity": "sha512-2zczyeNzeBcrT2HOysv52X9SH3tZoHfWJvVf6H0SIa74rfDKEl7hFpKNXnh3x8sIMLj5mZn05n5RCqGxCczcIg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "14.2.13", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "jsonc-parser": "3.1.0", "magic-string": "0.26.2", "ora": "5.4.1", @@ -3820,12 +5592,22 @@ } }, "node_modules/@ionic/angular-toolkit/node_modules/@schematics/angular": { +<<<<<<< HEAD "version": "14.2.12", "dev": true, "license": "MIT", "dependencies": { "@angular-devkit/core": "14.2.12", "@angular-devkit/schematics": "14.2.12", +======= + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.13.tgz", + "integrity": "sha512-MLxTpTU3E8QACQ/5c0sENMR2gRiMXpGaKeD5IHY+3wyU2fUSJVB0QPU/l1WhoyZbX8N9ospBgf5UEG7taVF9rg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "14.2.13", + "@angular-devkit/schematics": "14.2.13", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "jsonc-parser": "3.1.0" }, "engines": { @@ -3834,6 +5616,7 @@ "yarn": ">= 1.13.0" } }, +<<<<<<< HEAD "node_modules/@ionic/angular-toolkit/node_modules/ajv": { "version": "8.11.0", "dev": true, @@ -3870,6 +5653,24 @@ "node_modules/@ionic/core": { "version": "6.7.5", "license": "MIT", +======= + "node_modules/@ionic/angular-toolkit/node_modules/magic-string": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.2.tgz", + "integrity": "sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ionic/core": { + "version": "6.7.4", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.7.4.tgz", + "integrity": "sha512-IG6vQtt4xrJdas6k1CwqahD/BWsYK6Gi/BAIN8TumBmtfNMu38iOG6Dh05q4hCQzmDm2xDS/BVD3Qz7AmOKArA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@stencil/core": "^2.18.0", "ionicons": "^6.1.3", @@ -3878,8 +5679,9 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -3889,61 +5691,237 @@ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=12" + } + }, +<<<<<<< HEAD +======= + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, +<<<<<<< HEAD +======= + "node_modules/@isaacs/cliui/node_modules/string-width-cjs": { + "name": "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" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width-cjs/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/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi-cjs": { + "name": "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" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" + "node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/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, - "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/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-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -3955,6 +5933,7 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/@istanbuljs/load-nyc-config/node_modules/get-package-type": { "version": "0.1.0", "dev": true, @@ -3963,18 +5942,22 @@ "node": ">=8.0.0" } }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -3983,14 +5966,28 @@ "node": ">=6.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@jridgewell/set-array": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0.0" } }, +<<<<<<< HEAD "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "dev": true, @@ -3998,13 +5995,49 @@ }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.19", +======= + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "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/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, +<<<<<<< HEAD "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", "dev": true, @@ -4012,16 +6045,24 @@ "engines": { "node": ">=6.0.0" } +======= + "node_modules/@kurkle/color": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", + "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", + "dev": true }, "node_modules/@ngtools/webpack": { "version": "15.2.9", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-15.2.9.tgz", + "integrity": "sha512-nOXUGqKkAEMlCcrhkDwWDzcVdKNH7MNRUXfNzsFc9zdeR/5p3qt6SVMN7OOE3NREyI7P6nzARc3S+6QDBjf3Jg==", "dev": true, - "license": "MIT", "engines": { "node": "^14.20.0 || ^16.13.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", @@ -4034,8 +6075,14 @@ } }, "node_modules/@ngx-formly/core": { +<<<<<<< HEAD "version": "6.1.8", "license": "MIT", +======= + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.1.7.tgz", + "integrity": "sha512-hFale+MISRuRznbi4Q7HQaXDICl6wtMneJcnQGmYv8yjeaOYjBsogpD4cOeDf3GibrHYk7Ggh4mamGaLdCL65A==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "tslib": "^2.0.0" }, @@ -4045,8 +6092,14 @@ } }, "node_modules/@ngx-formly/ionic": { +<<<<<<< HEAD "version": "6.1.8", "license": "MIT", +======= + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@ngx-formly/ionic/-/ionic-6.1.7.tgz", + "integrity": "sha512-T1rXjM2L8LvbtE2xdeyStECHjipy7ZqmixI7uVJ/2+7i4frD30UisAW25+Kg1E3Bq2SpQ+De+tEg/B1kOGclWA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "tslib": "^2.0.0" }, @@ -4056,8 +6109,14 @@ } }, "node_modules/@ngx-formly/schematics": { +<<<<<<< HEAD "version": "6.1.8", "license": "MIT", +======= + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@ngx-formly/schematics/-/schematics-6.1.7.tgz", + "integrity": "sha512-My7Caz9zNS8NQKtAQTF21YIZnJZ9KZTlh1GPjydlYRpLp2zkfsEiu7nUDBFZV6e0/pLLnlPuaeEkXEuK8SPCZw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@angular-devkit/core": "^13.0.3", "@angular-devkit/schematics": "^13.0.3", @@ -4066,7 +6125,12 @@ }, "node_modules/@ngx-formly/schematics/node_modules/@angular-devkit/core": { "version": "13.3.11", +<<<<<<< HEAD "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.3.11.tgz", + "integrity": "sha512-rfqoLMRYhlz0wzKlHx7FfyIyQq8dKTsmbCoIVU1cEIH0gyTMVY7PbVzwRRcO6xp5waY+0hA+0Brriujpuhkm4w==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "ajv": "8.9.0", "ajv-formats": "2.1.1", @@ -4091,7 +6155,12 @@ }, "node_modules/@ngx-formly/schematics/node_modules/@angular-devkit/schematics": { "version": "13.3.11", +<<<<<<< HEAD "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.3.11.tgz", + "integrity": "sha512-ben+EGXpCrClnIVAAnEQmhQdKmnnqFhMp5BqMxgOslSYBAmCutLA6rBu5vsc8kZcGian1wt+lueF7G1Uk5cGBg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@angular-devkit/core": "13.3.11", "jsonc-parser": "3.0.0", @@ -4107,7 +6176,12 @@ }, "node_modules/@ngx-formly/schematics/node_modules/@schematics/angular": { "version": "13.3.11", +<<<<<<< HEAD "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.3.11.tgz", + "integrity": "sha512-imKBnKYEse0SBVELZO/753nkpt3eEgpjrYkB+AFWF9YfO/4RGnYXDHoH8CFkzxPH9QQCgNrmsVFNiYGS+P/S1A==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@angular-devkit/core": "13.3.11", "@angular-devkit/schematics": "13.3.11", @@ -4121,7 +6195,8 @@ }, "node_modules/@ngx-formly/schematics/node_modules/ajv": { "version": "8.9.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", + "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -4139,11 +6214,13 @@ }, "node_modules/@ngx-formly/schematics/node_modules/jsonc-parser": { "version": "3.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" }, "node_modules/@ngx-formly/schematics/node_modules/magic-string": { "version": "0.25.7", - "license": "MIT", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", "dependencies": { "sourcemap-codec": "^1.4.4" } @@ -4157,7 +6234,8 @@ }, "node_modules/@ngx-formly/schematics/node_modules/source-map": { "version": "0.7.3", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "engines": { "node": ">= 8" } @@ -4168,7 +6246,8 @@ }, "node_modules/@ngx-translate/core": { "version": "14.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-14.0.0.tgz", + "integrity": "sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==", "dependencies": { "tslib": "^2.3.0" }, @@ -4179,8 +6258,9 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -4232,16 +6312,18 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -4269,8 +6351,9 @@ }, "node_modules/@npmcli/fs": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -4278,10 +6361,57 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/@npmcli/git": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", + "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@npmcli/installed-package-contents": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", + "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", "dev": true, - "license": "ISC", "dependencies": { "npm-bundled": "^3.0.0", "npm-normalize-package-bin": "^3.0.0" @@ -4293,18 +6423,37 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@npmcli/node-gyp": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/@npmcli/promise-spawn": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", + "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", "dev": true, - "license": "ISC", "dependencies": { "which": "^3.0.0" }, @@ -4319,8 +6468,9 @@ }, "node_modules/@npmcli/promise-spawn/node_modules/which": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4333,8 +6483,9 @@ }, "node_modules/@npmcli/run-script": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", + "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^3.0.0", "@npmcli/promise-spawn": "^6.0.0", @@ -4453,8 +6604,9 @@ }, "node_modules/@npmcli/run-script/node_modules/which": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", + "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4467,8 +6619,9 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, - "license": "MIT", "optional": true, "engines": { "node": ">=14" @@ -4476,8 +6629,12 @@ }, "node_modules/@schematics/angular": { "version": "15.2.9", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.9.tgz", + "integrity": "sha512-0Lit6TLNUwcAYiEkXgZp3vY9xAO1cnZCBXuUcp+6v+Ddnrt2w/YOiGe74p21cYe0StkTpTljsqsKBTiX7TMjQg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@angular-devkit/core": "15.2.9", "@angular-devkit/schematics": "15.2.9", @@ -4489,10 +6646,24 @@ "yarn": ">= 1.13.0" } }, +<<<<<<< HEAD "node_modules/@sigstore/bundle": { "version": "1.1.0", "dev": true, "license": "Apache-2.0", +======= + "node_modules/@schematics/angular/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/@sigstore/bundle": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.1.0.tgz", + "integrity": "sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@sigstore/protobuf-specs": "^0.2.0" }, @@ -4500,18 +6671,32 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD "node_modules/@sigstore/bundle/node_modules/@sigstore/protobuf-specs": { "version": "0.2.1", "dev": true, "license": "Apache-2.0", +======= + "node_modules/@sigstore/protobuf-specs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", + "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/@sigstore/sign": { "version": "1.0.0", +<<<<<<< HEAD "dev": true, "license": "Apache-2.0", +======= + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-1.0.0.tgz", + "integrity": "sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@sigstore/bundle": "^1.1.0", "@sigstore/protobuf-specs": "^0.2.0", @@ -4521,18 +6706,34 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD "node_modules/@sigstore/sign/node_modules/@sigstore/protobuf-specs": { "version": "0.2.1", "dev": true, "license": "Apache-2.0", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" +======= + "node_modules/@sigstore/sign/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { "version": "11.1.1", +<<<<<<< HEAD "dev": true, "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^17.0.0", @@ -4556,16 +6757,28 @@ }, "node_modules/@sigstore/sign/node_modules/minipass": { "version": "5.0.0", +<<<<<<< HEAD "dev": true, "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=8" } }, "node_modules/@sigstore/sign/node_modules/minipass-fetch": { "version": "3.0.4", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -4579,21 +6792,35 @@ } }, "node_modules/@sigstore/sign/node_modules/minipass-fetch/node_modules/minipass": { +<<<<<<< HEAD "version": "7.0.3", "dev": true, "license": "ISC", +======= + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/@sigstore/tuf": { "version": "1.0.3", +<<<<<<< HEAD "dev": true, "license": "Apache-2.0", +======= + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-1.0.3.tgz", + "integrity": "sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "@sigstore/protobuf-specs": "^0.2.0", "tuf-js": "^1.1.7" }, +<<<<<<< HEAD "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -4672,18 +6899,22 @@ "debug": "^4.3.4", "make-fetch-happen": "^11.1.1" }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/@socket.io/component-emitter": { "version": "3.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true }, "node_modules/@stencil/core": { "version": "2.22.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.22.3.tgz", + "integrity": "sha512-kmVA0M/HojwsfkeHsifvHVIYe4l5tin7J5+DLgtl8h6WWfiMClND5K3ifCXXI2ETDNKiEk21p6jql3Fx9o2rng==", "bin": { "stencil": "bin/stencil" }, @@ -4694,44 +6925,56 @@ }, "node_modules/@tootallnate/once": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", +<<<<<<< HEAD "dev": true, "license": "MIT" +======= + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/@tufjs/canonical-json": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz", + "integrity": "sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==", "dev": true, - "license": "MIT", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/@tufjs/models": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-1.0.4.tgz", + "integrity": "sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==", "dev": true, - "license": "MIT", "dependencies": { "@tufjs/canonical-json": "1.0.0", "minimatch": "^9.0.0" @@ -4742,16 +6985,21 @@ }, "node_modules/@tufjs/models/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@tufjs/models/node_modules/minimatch": { "version": "9.0.3", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4763,52 +7011,106 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.2", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, - "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, +<<<<<<< HEAD "node_modules/@types/chart.js": { "version": "2.9.38", "license": "MIT", "dependencies": { "moment": "^2.10.2" +======= + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "dependencies": { + "@types/node": "*" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/@types/connect": { - "version": "3.4.35", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, +<<<<<<< HEAD +======= + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dev": true, - "license": "MIT", "dependencies": { + "@types/express-serve-static-core": "*", "@types/node": "*" } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@types/cookie": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, - "license": "MIT" + "dependencies": { + "@types/node": "*" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@types/eslint": { - "version": "8.4.6", + "version": "8.56.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", + "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, +<<<<<<< HEAD +======= + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@types/estree": { "version": "0.0.51", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true }, "node_modules/@types/express": { - "version": "4.17.17", + "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", @@ -4817,9 +7119,10 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -4839,42 +7142,84 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.1", - "dev": true, - "license": "MIT" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true }, +<<<<<<< HEAD "node_modules/@types/jasmine": { "version": "4.3.5", "dev": true, "license": "MIT" +======= + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.3.2.tgz", + "integrity": "sha512-lKkWBcbxEZX/7nxPqEtv/OjPLaBa2j0o+hmv5Yn83b/+11C1kfBAkgvmrb13WDkmizUJ3B+jYrWh4M0YRtrzEQ==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/@types/jasminewd2": { "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.10.tgz", + "integrity": "sha512-J7mDz7ovjwjc+Y9rR9rY53hFWKATcIkrr9DwQWmOas4/pnIPJTXawnzjwpHm3RSxz/e3ZVUvQ7cRbd5UQLo10g==", "dev": true, - "license": "MIT", "dependencies": { "@types/jasmine": "*" } }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "dev": true, - "license": "MIT" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true }, "node_modules/@types/json5": { "version": "0.0.29", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true }, "node_modules/@types/mime": { - "version": "1.3.2", - "dev": true, - "license": "MIT" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true }, "node_modules/@types/node": { +<<<<<<< HEAD "version": "20.5.9", +======= + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", + "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", + "dev": true + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT" + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true }, "node_modules/@types/node-forge": { "version": "1.3.8", @@ -4886,54 +7231,81 @@ }, "node_modules/@types/q": { "version": "0.0.32", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", + "integrity": "sha512-qYi3YV9inU/REEfxwVcGZzbS3KG/Xs90lv0Pr+lDtuVjBPGd1A+eciXzVSaRvLify132BfcvhvEjeVahrUl0Ug==", + "dev": true }, "node_modules/@types/qs": { - "version": "6.9.7", - "dev": true, - "license": "MIT" + "version": "6.9.11", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", + "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==", + "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "dev": true, - "license": "MIT" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true }, "node_modules/@types/retry": { "version": "0.12.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true }, "node_modules/@types/selenium-webdriver": { "version": "3.0.26", "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.26.tgz", "integrity": "sha512-dyIGFKXfUFiwkMfNGn1+F6b80ZjR3uSYv1j6xVJSDlft5waZ2cwkHW4e7zNzvq7hiEackcgvBpmnXZrI1GltPg==", "dev": true +<<<<<<< HEAD +======= + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/@types/send": { - "version": "0.17.1", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, - "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, +<<<<<<< HEAD "node_modules/@types/send/node_modules/@types/mime": { "version": "1.3.3", "dev": true, "license": "MIT" +======= + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "dependencies": { + "@types/express": "*" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/@types/serve-static": { - "version": "1.15.2", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/mime": "*", "@types/node": "*" } }, +<<<<<<< HEAD "node_modules/@types/uuid": { "version": "9.0.3", "dev": true, @@ -4941,8 +7313,37 @@ }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.6.0", +======= + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/uuid": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.0.tgz", + "integrity": "sha512-rClGrMuyS/3j0ETa1Ui7s6GkLhfZGKZL3ZrChLeAiACBE/tRc1wq8SNZESUuluxhLj9FkUefRs2l6bCIArWBiQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.6.0", @@ -4973,6 +7374,7 @@ } } }, +<<<<<<< HEAD "node_modules/@typescript-eslint/eslint-plugin/node_modules/@types/json-schema": { "version": "7.0.13", "dev": true, @@ -4985,8 +7387,30 @@ }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { "version": "6.6.0", +======= + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.0.tgz", + "integrity": "sha512-DnGZuNU2JN3AYwddYIqrVkYW0uUQdv0AY+kz2M25euVNlujcN2u+rJgfJsBFlUEzBB6OQkUqSZPyuTLf2bP5mw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "6.6.0", "@typescript-eslint/utils": "6.6.0", @@ -5010,9 +7434,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { +<<<<<<< HEAD "version": "6.6.0", "dev": true, "license": "MIT", +======= + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -5022,12 +7453,22 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { +<<<<<<< HEAD "version": "6.6.0", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "6.6.0", "@typescript-eslint/visitor-keys": "6.6.0", +======= + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", + "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "@typescript-eslint/visitor-keys": "6.2.0", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -5048,9 +7489,14 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { +<<<<<<< HEAD "version": "6.6.0", +======= + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.0.tgz", + "integrity": "sha512-RCFrC1lXiX1qEZN8LmLrxYRhOkElEsPKTVSNout8DMzf8PeWoQG7Rxz2SadpJa3VSh5oYKGwt7j7X/VRg+Y3OQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", @@ -5071,10 +7517,55 @@ "eslint": "^7.0.0 || ^8.0.0" } }, +<<<<<<< HEAD "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { "version": "6.0.0", "dev": true, "license": "ISC", +======= + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "yallist": "^4.0.0" }, @@ -5084,8 +7575,14 @@ }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { "version": "7.5.4", +<<<<<<< HEAD "dev": true, "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "lru-cache": "^6.0.0" }, @@ -5096,10 +7593,29 @@ "node": ">=10" } }, +<<<<<<< HEAD +======= + "node_modules/@typescript-eslint/eslint-plugin/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@typescript-eslint/parser": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.0.tgz", + "integrity": "sha512-igVYOqtiK/UsvKAmmloQAruAdUHihsOCvplJpplPZ+3h4aDkC/UKZZNKgB6h93ayuYLuEymU3h8nF1xMRbh37g==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "6.2.0", "@typescript-eslint/types": "6.2.0", @@ -5125,8 +7641,9 @@ }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.0.tgz", + "integrity": "sha512-1ZMNVgm5nnHURU8ZSJ3snsHzpFeNK84rdZjluEVBGNu7jDymfqceB3kdIZ6A4xCfEFFhRIB6rF8q/JIqJd2R0Q==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "6.2.0", "@typescript-eslint/visitor-keys": "6.2.0" @@ -5139,6 +7656,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, +<<<<<<< HEAD "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { "version": "6.2.0", "dev": true, @@ -5283,9 +7801,13 @@ } }, "node_modules/@typescript-eslint/types": { +======= + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.0.tgz", + "integrity": "sha512-1nRRaDlp/XYJQLvkQJG5F3uBTno5SHPT7XVcJ5n1/k2WfNI28nJsvLakxwZRNY5spuatEKO7d5nZWsQpkqXwBA==", "dev": true, - "license": "MIT", "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -5294,10 +7816,11 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.0.tgz", + "integrity": "sha512-Mts6+3HQMSM+LZCglsc2yMIny37IhUgp1Qe8yJUYVyO6rHP7/vN0vajKu3JvHCBIy8TSiKddJ/Zwu80jhnGj1w==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "6.2.0", "@typescript-eslint/visitor-keys": "6.2.0", @@ -5320,6 +7843,7 @@ } } }, +<<<<<<< HEAD "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": { "version": "6.2.0", "dev": true, @@ -5363,29 +7887,26 @@ }, "node_modules/@typescript-eslint/utils": { "version": "5.48.2", +======= + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.0.tgz", + "integrity": "sha512-QbaYUQVKKo9bgCzpjz45llCfwakyoxHetIy8CAvYCtd16Zu1KrpzNHofwF8kGkpPOxZB2o6kz+0nqH8ZkIzuoQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.48.2", - "@typescript-eslint/types": "5.48.2", - "@typescript-eslint/typescript-estree": "5.48.2", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" + "@typescript-eslint/types": "6.2.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, +<<<<<<< HEAD "node_modules/@typescript-eslint/utils/node_modules/@types/json-schema": { "version": "7.0.13", "dev": true, @@ -5398,8 +7919,75 @@ }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { "version": "5.48.2", +======= + "node_modules/@typescript-eslint/parser/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.48.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz", + "integrity": "sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.48.2", "@typescript-eslint/visitor-keys": "5.48.2" @@ -5412,10 +8000,38 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/type-utils": { "version": "5.48.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz", + "integrity": "sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.48.2", + "@typescript-eslint/utils": "5.48.2", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.48.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.2.tgz", + "integrity": "sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==", "dev": true, - "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5424,10 +8040,11 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/typescript-estree": { "version": "5.48.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz", + "integrity": "sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "5.48.2", "@typescript-eslint/visitor-keys": "5.48.2", @@ -5444,16 +8061,72 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.48.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.2.tgz", + "integrity": "sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.48.2", + "@typescript-eslint/types": "5.48.2", + "@typescript-eslint/typescript-estree": "5.48.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys": { "version": "5.48.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz", + "integrity": "sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==", "dev": true, - "license": "MIT", "dependencies": { "@typescript-eslint/types": "5.48.2", "eslint-visitor-keys": "^3.3.0" @@ -5466,6 +8139,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, +<<<<<<< HEAD "node_modules/@typescript-eslint/utils/node_modules/tslib": { "version": "1.14.1", "dev": true, @@ -5518,10 +8192,13 @@ "dev": true, "license": "ISC" }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/@webassemblyjs/ast": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1" @@ -5529,23 +8206,27 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", @@ -5554,13 +8235,15 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", @@ -5570,29 +8253,33 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "dev": true, - "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { "version": "1.11.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", @@ -5606,8 +8293,9 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.1", @@ -5618,8 +8306,9 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-buffer": "1.11.1", @@ -5629,8 +8318,9 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/helper-api-error": "1.11.1", @@ -5642,8 +8332,9 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.1", "@xtuc/long": "4.2.2" @@ -5651,33 +8342,40 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true }, "node_modules/@xtuc/long": { "version": "4.2.2", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true }, "node_modules/abab": { "version": "2.0.6", - "dev": true, - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true }, "node_modules/abbrev": { "version": "1.1.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, - "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -5687,9 +8385,10 @@ } }, "node_modules/acorn": { - "version": "8.11.2", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5697,26 +8396,41 @@ "node": ">=0.4.0" } }, +<<<<<<< HEAD +======= + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.2.0", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", "dev": true, - "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" @@ -5738,8 +8452,9 @@ }, "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, - "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -5751,16 +8466,18 @@ }, "node_modules/adm-zip": { "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/agent-base": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, - "license": "MIT", "dependencies": { "debug": "4" }, @@ -5770,8 +8487,12 @@ }, "node_modules/agentkeepalive": { "version": "4.5.0", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "humanize-ms": "^1.2.1" }, @@ -5781,8 +8502,9 @@ }, "node_modules/aggregate-error": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, - "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -5792,8 +8514,14 @@ } }, "node_modules/ajv": { +<<<<<<< HEAD "version": "8.12.0", "license": "MIT", +======= + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -5807,7 +8535,8 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dependencies": { "ajv": "^8.0.0" }, @@ -5822,8 +8551,9 @@ }, "node_modules/ajv-keywords": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -5844,27 +8574,31 @@ }, "node_modules/angular-mydatepicker": { "version": "0.11.5", - "license": "MIT", + "resolved": "https://registry.npmjs.org/angular-mydatepicker/-/angular-mydatepicker-0.11.5.tgz", + "integrity": "sha512-nKXUA3NhzMJ02jX+AiqpEr0kl2lCS3tGaFeHcyBFhwlDao9BO9i3403NXaFliOCeN2M4VvUNQs8pggLE7DECIA==", "dependencies": { "tslib": "^1.9.0" } }, "node_modules/angular-mydatepicker/node_modules/tslib": { "version": "1.14.1", - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/ansi-colors": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -5877,26 +8611,29 @@ }, "node_modules/ansi-html-community": { "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "dev": true, "engines": [ "node >= 0.8.0" ], - "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" } }, "node_modules/ansi-regex": { "version": "5.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -5904,23 +8641,42 @@ "node": ">=4" } }, +<<<<<<< HEAD +======= + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/aproba": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true }, "node_modules/are-docs-informative": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, - "license": "MIT", "engines": { "node": ">=14" } }, "node_modules/are-we-there-yet": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", "dev": true, - "license": "ISC", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -5962,13 +8718,15 @@ }, "node_modules/arg": { "version": "4.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -5980,12 +8738,14 @@ }, "node_modules/aria-query": { "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "deep-equal": "^2.0.5" } }, +<<<<<<< HEAD "node_modules/aria-query/node_modules/call-bind": { "version": "1.0.5", "dev": true, @@ -6388,6 +9148,34 @@ "license": "MIT", "dependencies": { "call-bind": "^1.0.2", +======= + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "define-properties": "^1.2.0", "es-abstract": "^1.22.1", "get-intrinsic": "^1.2.1", @@ -6400,6 +9188,7 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/array-includes/node_modules/call-bind": { "version": "1.0.5", "dev": true, @@ -6698,25 +9487,35 @@ "dev": true, "license": "MIT", "engines": { +======= + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node": ">=8" } }, "node_modules/array-uniq": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/array.prototype.flat": { - "version": "1.3.1", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -7028,13 +9827,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -7044,6 +9844,7 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/array.prototype.flatmap/node_modules/call-bind": { "version": "1.0.5", "dev": true, @@ -7353,6 +10154,18 @@ "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", "define-properties": "^1.2.0", +======= + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "get-intrinsic": "^1.2.1", "is-array-buffer": "^3.0.2", "is-shared-array-buffer": "^1.0.2" @@ -7364,6 +10177,7 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/arraybuffer.prototype.slice/node_modules/call-bind": { "version": "1.0.5", "dev": true, @@ -7470,10 +10284,13 @@ "url": "https://github.com/sponsors/ljharb" } }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/arrify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7504,6 +10321,8 @@ }, "node_modules/autoprefixer": { "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", "dev": true, "funding": [ { @@ -7515,7 +10334,6 @@ "url": "https://tidelift.com/funding/github/npm/autoprefixer" } ], - "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "caniuse-lite": "^1.0.30001426", @@ -7553,8 +10371,9 @@ }, "node_modules/available-typed-arrays": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7564,8 +10383,9 @@ }, "node_modules/aws-sign2": { "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "*" } @@ -7578,8 +10398,9 @@ }, "node_modules/axobject-query": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", + "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "deep-equal": "^2.0.5" } @@ -7893,8 +10714,9 @@ }, "node_modules/babel-loader": { "version": "9.1.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz", + "integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==", "dev": true, - "license": "MIT", "dependencies": { "find-cache-dir": "^3.3.2", "schema-utils": "^4.0.0" @@ -7932,8 +10754,9 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -7968,8 +10791,9 @@ }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", @@ -7989,16 +10813,18 @@ }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "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.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3", "core-js-compat": "^3.25.1" @@ -8052,8 +10878,9 @@ }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3" }, @@ -8063,11 +10890,14 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -8081,21 +10911,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/base64id": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", "dev": true, - "license": "MIT", "engines": { "node": "^4.5.0 || >= 5.9" } }, "node_modules/batch": { "version": "0.6.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -8108,23 +10939,26 @@ }, "node_modules/big.js": { "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true, - "license": "MIT", "engines": { "node": "*" } }, "node_modules/binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/bl": { "version": "4.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -8160,8 +10994,9 @@ }, "node_modules/blocking-proxy": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz", + "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==", "dev": true, - "license": "MIT", "dependencies": { "minimist": "^1.2.0" }, @@ -8182,8 +11017,9 @@ }, "node_modules/body-parser": { "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, - "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -8203,18 +11039,29 @@ "npm": "1.2.8000 || >= 1.4.16" } }, +<<<<<<< HEAD "node_modules/body-parser/node_modules/content-type": { "version": "1.0.5", "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" +======= + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -8236,8 +11083,9 @@ }, "node_modules/body-parser/node_modules/iconv-lite": { "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, - "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -8260,19 +11108,9 @@ }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/body-parser/node_modules/on-finished": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/body-parser/node_modules/raw-body": { "version": "2.5.1", @@ -8330,25 +11168,26 @@ } }, "node_modules/bonjour-service": { - "version": "1.1.1", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dev": true, - "license": "MIT", "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "node_modules/boolbase": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -8356,8 +11195,9 @@ }, "node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "devOptional": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -8397,6 +11237,8 @@ }, "node_modules/browserslist": { "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, "funding": [ { @@ -8408,7 +11250,6 @@ "url": "https://tidelift.com/funding/github/npm/browserslist" } ], - "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001449", "electron-to-chromium": "^1.4.284", @@ -8424,16 +11265,18 @@ }, "node_modules/browserstack": { "version": "1.6.1", + "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.6.1.tgz", + "integrity": "sha512-GxtFjpIaKdbAyzHfFDKixKO8IBT7wR3NjbzrGc78nNs/Ciys9wU3/nBtsqsWv5nDSrdI5tz0peKuzCPuNXNUiw==", "dev": true, - "license": "MIT", "dependencies": { "https-proxy-agent": "^2.2.1" } }, "node_modules/browserstack/node_modules/agent-base": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", "dev": true, - "license": "MIT", "dependencies": { "es6-promisify": "^5.0.0" }, @@ -8443,16 +11286,18 @@ }, "node_modules/browserstack/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/browserstack/node_modules/https-proxy-agent": { "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^4.3.0", "debug": "^3.1.0" @@ -8463,6 +11308,8 @@ }, "node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -8477,7 +11324,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -8485,8 +11331,9 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, "node_modules/buffer/node_modules/ieee754": { "version": "1.2.1", @@ -8508,24 +11355,27 @@ }, "node_modules/builtins": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", "dev": true, - "license": "MIT", "dependencies": { "semver": "^7.0.0" } }, "node_modules/bytes": { - "version": "3.1.2", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/cacache": { "version": "17.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.0.4.tgz", + "integrity": "sha512-Z/nL3gU+zTUjz5pCA5vVjYM8pmaw2kxM7JEiE0fv3w77Wj+sFbi70CrBruUWH0uNcEdvLDixFpgA2JM4F4DBjA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -8545,6 +11395,7 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD "node_modules/cacache/node_modules/brace-expansion": { "version": "2.0.1", "dev": true, @@ -8640,25 +11491,57 @@ "version": "1.0.2", "dev": true, "license": "ISC" +======= + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { +<<<<<<< HEAD "version": "1.0.30001527", +======= + "version": "1.0.30001576", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", + "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, "funding": [ { @@ -8673,18 +11556,19 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/caseless": { "version": "0.12.0", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true }, "node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -8715,34 +11599,45 @@ }, "node_modules/chardet": { "version": "0.7.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true }, "node_modules/chart.js": { - "version": "2.9.4", - "license": "MIT", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz", + "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==", "dependencies": { - "chartjs-color": "^2.1.0", - "moment": "^2.10.2" + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=7" } }, - "node_modules/chartjs-color": { - "version": "2.4.1", - "license": "MIT", - "dependencies": { - "chartjs-color-string": "^0.6.0", - "color-convert": "^1.9.3" + "node_modules/chartjs-adapter-date-fns": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-3.0.0.tgz", + "integrity": "sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg==", + "peerDependencies": { + "chart.js": ">=2.8.0", + "date-fns": ">=2.0.0" } }, - "node_modules/chartjs-color-string": { - "version": "0.6.0", - "license": "MIT", + "node_modules/chartjs-plugin-zoom": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-2.0.1.tgz", + "integrity": "sha512-ogOmLu6e+Q7E1XWOCOz9YwybMslz9qNfGV2a+qjfmqJYpsw5ZMoRHZBUyW+NGhkpQ5PwwPA/+rikHpBZb7PZuA==", "dependencies": { - "color-name": "^1.0.0" + "hammerjs": "^2.0.8" + }, + "peerDependencies": { + "chart.js": ">=3.2.0" } }, "node_modules/chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "devOptional": true, "funding": [ { @@ -8750,7 +11645,6 @@ "url": "https://paulmillr.com/funding/" } ], - "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -8833,35 +11727,40 @@ }, "node_modules/chownr": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/chrome-trace-event": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/classlist.js": { "version": "1.1.20150312", - "license": "Dedicated to the public domain" + "resolved": "https://registry.npmjs.org/classlist.js/-/classlist.js-1.1.20150312.tgz", + "integrity": "sha512-eR8yB970+yGslcTnJnROX2icsMa8v/KVLv/sgv3NhSvZSHgam64XNSF2TyJnKIfsnTFJBcTdrIneYqUIrvxLpg==" }, "node_modules/clean-stack": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/cli-cursor": { "version": "3.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -8869,9 +11768,16 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/cli-cursor/node_modules/mimic-fn": { "version": "2.1.0", "license": "MIT", +======= + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=6" } @@ -8906,20 +11812,25 @@ }, "node_modules/cli-width": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, - "license": "ISC", "engines": { "node": ">= 10" } }, "node_modules/cliui": { - "version": "7.0.4", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/cliui/node_modules/ansi-styles": { @@ -8997,15 +11908,17 @@ }, "node_modules/clone": { "version": "1.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "engines": { "node": ">=0.8" } }, "node_modules/clone-deep": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, - "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -9017,39 +11930,56 @@ }, "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==", + "dev": true, "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-convert/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==", + "dev": true }, "node_modules/color-name": { "version": "1.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/color-support": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, - "license": "ISC", "bin": { "color-support": "bin.js" } }, +<<<<<<< HEAD +======= + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/colors": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.1.90" } }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -9059,32 +11989,37 @@ }, "node_modules/commander": { "version": "7.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "engines": { "node": ">= 10" } }, "node_modules/comment-parser": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 12.0.0" } }, "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/compare-versions": { "version": "6.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==" }, "node_modules/compressible": { "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, - "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -9094,8 +12029,9 @@ }, "node_modules/compression": { "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, - "license": "MIT", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -9109,26 +12045,26 @@ "node": ">= 0.8.0" } }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/compression/node_modules/safe-buffer": { "version": "5.1.2", @@ -9145,13 +12081,15 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/connect": { "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", "dev": true, - "license": "MIT", "dependencies": { "debug": "2.6.9", "finalhandler": "1.1.2", @@ -9164,24 +12102,32 @@ }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/connect/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/connect/node_modules/finalhandler": { "version": "1.1.2", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -9197,8 +12143,30 @@ }, "node_modules/connect/node_modules/ms": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/connect/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "dev": true, - "license": "MIT" + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } }, "node_modules/connect/node_modules/on-finished": { "version": "2.3.0", @@ -9245,13 +12213,15 @@ }, "node_modules/console-control-strings": { "version": "1.1.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -9259,23 +12229,44 @@ "node": ">= 0.6" } }, +<<<<<<< HEAD +======= + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/cookie": { - "version": "0.4.2", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true }, "node_modules/copy-anything": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", "dev": true, - "license": "MIT", "dependencies": { "is-what": "^3.14.1" }, @@ -9285,8 +12276,9 @@ }, "node_modules/copy-webpack-plugin": { "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", "dev": true, - "license": "MIT", "dependencies": { "fast-glob": "^3.2.11", "glob-parent": "^6.0.1", @@ -9339,8 +12331,9 @@ }, "node_modules/copy-webpack-plugin/node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -9348,6 +12341,7 @@ "node": ">=10.13.0" } }, +<<<<<<< HEAD "node_modules/copy-webpack-plugin/node_modules/globby": { "version": "13.2.2", "dev": true, @@ -9454,12 +12448,64 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", +======= + "node_modules/core-js-compat": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", + "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", + "dev": true, + "dependencies": { + "browserslist": "^4.22.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat/node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true }, "node_modules/cors": { "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, - "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -9478,8 +12524,9 @@ }, "node_modules/cosmiconfig": { "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, - "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -9491,28 +12538,17 @@ "node": ">=10" } }, - "node_modules/cosmiconfig/node_modules/@types/parse-json": { - "version": "4.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/cosmiconfig/node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "node_modules/critters": { "version": "0.0.16", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.16.tgz", + "integrity": "sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A==", "dev": true, - "license": "Apache-2.0", "dependencies": { "chalk": "^4.1.0", "css-select": "^4.2.0", @@ -9524,8 +12560,9 @@ }, "node_modules/critters/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -9538,8 +12575,9 @@ }, "node_modules/critters/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -9553,8 +12591,9 @@ }, "node_modules/critters/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -9564,8 +12603,9 @@ }, "node_modules/critters/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -9596,8 +12636,9 @@ }, "node_modules/critters/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -9607,8 +12648,9 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -9666,8 +12708,9 @@ }, "node_modules/css-loader": { "version": "6.7.3", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz", + "integrity": "sha512-qhOH1KlBMnZP8FzRO6YCH9UHXQhVMcEGLyNdb7Hv2cpcmJbW0YrddO+tG1ab5nT41KpHIYGsbeHqxB9xPu1pKQ==", "dev": true, - "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.19", @@ -9724,8 +12767,9 @@ }, "node_modules/css-select": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -9750,8 +12794,9 @@ }, "node_modules/css-what": { "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -9761,8 +12806,9 @@ }, "node_modules/cssesc": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, - "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -9772,12 +12818,14 @@ }, "node_modules/custom-event": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true }, "node_modules/d3": { "version": "7.8.5", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", + "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -9816,7 +12864,12 @@ }, "node_modules/d3-array": { "version": "3.2.4", +<<<<<<< HEAD "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "internmap": "1 - 2" }, @@ -9833,14 +12886,16 @@ }, "node_modules/d3-axis": { "version": "3.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", "engines": { "node": ">=12" } }, "node_modules/d3-brush": { "version": "3.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -9854,7 +12909,8 @@ }, "node_modules/d3-chord": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", "dependencies": { "d3-path": "1 - 3" }, @@ -9864,14 +12920,20 @@ }, "node_modules/d3-color": { "version": "3.1.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "engines": { "node": ">=12" } }, "node_modules/d3-contour": { "version": "4.0.2", +<<<<<<< HEAD "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "d3-array": "^3.2.0" }, @@ -9881,7 +12943,12 @@ }, "node_modules/d3-delaunay": { "version": "6.0.4", +<<<<<<< HEAD "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "delaunator": "5" }, @@ -9891,14 +12958,16 @@ }, "node_modules/d3-dispatch": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", "engines": { "node": ">=12" } }, "node_modules/d3-drag": { "version": "3.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -9909,7 +12978,8 @@ }, "node_modules/d3-dsv": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", "dependencies": { "commander": "7", "iconv-lite": "0.6", @@ -9946,14 +13016,16 @@ }, "node_modules/d3-ease": { "version": "3.0.1", - "license": "BSD-3-Clause", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", "engines": { "node": ">=12" } }, "node_modules/d3-fetch": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", "dependencies": { "d3-dsv": "1 - 3" }, @@ -9963,7 +13035,8 @@ }, "node_modules/d3-force": { "version": "3.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", @@ -9975,14 +13048,20 @@ }, "node_modules/d3-format": { "version": "3.1.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", "engines": { "node": ">=12" } }, "node_modules/d3-geo": { "version": "3.1.0", +<<<<<<< HEAD "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -9992,14 +13071,16 @@ }, "node_modules/d3-hierarchy": { "version": "3.1.2", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", "engines": { "node": ">=12" } }, "node_modules/d3-interpolate": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "dependencies": { "d3-color": "1 - 3" }, @@ -10009,35 +13090,44 @@ }, "node_modules/d3-path": { "version": "3.1.0", +<<<<<<< HEAD "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=12" } }, "node_modules/d3-polygon": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", "engines": { "node": ">=12" } }, "node_modules/d3-quadtree": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", "engines": { "node": ">=12" } }, "node_modules/d3-random": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", "engines": { "node": ">=12" } }, "node_modules/d3-scale": { "version": "4.0.2", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", @@ -10051,7 +13141,8 @@ }, "node_modules/d3-scale-chromatic": { "version": "3.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -10062,14 +13153,20 @@ }, "node_modules/d3-selection": { "version": "3.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "engines": { "node": ">=12" } }, "node_modules/d3-shape": { "version": "3.2.0", +<<<<<<< HEAD "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "d3-path": "^3.1.0" }, @@ -10079,7 +13176,12 @@ }, "node_modules/d3-time": { "version": "3.1.0", +<<<<<<< HEAD "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "d3-array": "2 - 3" }, @@ -10089,7 +13191,8 @@ }, "node_modules/d3-time-format": { "version": "4.1.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", "dependencies": { "d3-time": "1 - 3" }, @@ -10099,14 +13202,16 @@ }, "node_modules/d3-timer": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", "engines": { "node": ">=12" } }, "node_modules/d3-transition": { "version": "3.0.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -10123,7 +13228,8 @@ }, "node_modules/d3-zoom": { "version": "3.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -10149,7 +13255,8 @@ }, "node_modules/date-fns": { "version": "2.30.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "dependencies": { "@babel/runtime": "^7.21.0" }, @@ -10162,8 +13269,14 @@ } }, "node_modules/date-fns/node_modules/@babel/runtime": { +<<<<<<< HEAD "version": "7.22.15", "license": "MIT", +======= + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", + "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -10172,13 +13285,29 @@ } }, "node_modules/date-fns/node_modules/regenerator-runtime": { +<<<<<<< HEAD "version": "0.14.0", "license": "MIT" +======= + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/debug": { "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -10193,21 +13322,65 @@ }, "node_modules/decamelize": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, +<<<<<<< HEAD +======= + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-equal/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/deep-is": { "version": "0.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "node_modules/default-gateway": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, @@ -10215,17 +13388,38 @@ "node": ">= 10" } }, +<<<<<<< HEAD "node_modules/define-data-property": { "version": "1.1.1", "dev": true, "license": "MIT", "dependencies": { +======= + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.0" }, "engines": { "node": ">= 0.4" +<<<<<<< HEAD } }, "node_modules/define-data-property/node_modules/has-property-descriptors": { @@ -10237,20 +13431,44 @@ }, "funding": { "url": "https://github.com/sponsors/ljharb" +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "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" } }, +<<<<<<< HEAD +======= + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/del": { "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha512-Z4fzpbIRjOu7lO5jCETSWoqUDVe0IPOlfugBsF6suen2LKDlVb4QZpKEM9P+buNJ4KI1eN7I083w/pbKUpsrWQ==", "dev": true, - "license": "MIT", "dependencies": { "globby": "^5.0.0", "is-path-cwd": "^1.0.0", @@ -10266,19 +13484,49 @@ }, "node_modules/del/node_modules/array-union": { "version": "1.0.2", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "array-uniq": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, +<<<<<<< HEAD +======= + "node_modules/del/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/del/node_modules/globby": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha512-HJRTIH2EeH44ka+LWig+EqT2ONSYpVlNfx6pyd592/VF1TbfljJ7elwie7oSwcViLGqOdWocSdu2txwBF9bjmQ==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^1.0.1", "arrify": "^1.0.0", @@ -10291,14 +13539,23 @@ "node": ">=0.10.0" } }, +<<<<<<< HEAD "node_modules/del/node_modules/is-path-cwd": { "version": "1.0.0", "dev": true, "license": "MIT", +======= + "node_modules/del/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=0.10.0" } }, +<<<<<<< HEAD "node_modules/del/node_modules/is-path-in-cwd": { "version": "1.0.1", "dev": true, @@ -10326,10 +13583,13 @@ "dev": true, "license": "(WTFPL OR MIT)" }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/del/node_modules/rimraf": { "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -10339,7 +13599,8 @@ }, "node_modules/delaunator": { "version": "5.0.0", - "license": "ISC", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", "dependencies": { "robust-predicates": "^3.0.0" } @@ -10350,37 +13611,42 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/delegates": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true }, "node_modules/depd": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/dependency-graph": { "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/destroy": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -10388,26 +13654,30 @@ }, "node_modules/detect-node": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true }, "node_modules/di": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true }, "node_modules/diff": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -10415,6 +13685,7 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/dir-glob/node_modules/path-type": { "version": "4.0.0", "dev": true, @@ -10428,10 +13699,25 @@ "dev": true, "license": "MIT" }, +======= + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/doctrine": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -10441,8 +13727,9 @@ }, "node_modules/dom-serialize": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", "dev": true, - "license": "MIT", "dependencies": { "custom-event": "~1.0.0", "ent": "~2.2.0", @@ -10460,8 +13747,9 @@ }, "node_modules/dom-serializer": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dev": true, - "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -10473,19 +13761,21 @@ }, "node_modules/domelementtype": { "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } - ], - "license": "BSD-2-Clause" + ] }, "node_modules/domhandler": { "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" }, @@ -10498,8 +13788,9 @@ }, "node_modules/domutils": { "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -10511,8 +13802,9 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/ecc-jsbn": { "version": "0.1.2", @@ -10526,44 +13818,57 @@ }, "node_modules/ee-first": { "version": "1.1.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true }, "node_modules/electron-to-chromium": { +<<<<<<< HEAD "version": "1.4.508", "dev": true, "license": "ISC" +======= + "version": "1.4.628", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.628.tgz", + "integrity": "sha512-2k7t5PHvLsufpP6Zwk0nof62yLOsCf032wZx7/q0mv8gwlXjhcxI3lz6f0jBr0GrnWKcm3burXzI3t5IrcdUxw==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/emojis-list": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/encodeurl": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/encoding": { "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "iconv-lite": "^0.6.2" } }, +<<<<<<< HEAD "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", "dev": true, @@ -10574,38 +13879,116 @@ }, "engines": { "node": ">=0.10.0" +======= + "node_modules/engine.io": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", + "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "dev": true, + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/ent": { "version": "2.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", + "dev": true }, "node_modules/entities": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "dev": true, - "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/env-paths": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/err-code": { "version": "2.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true }, "node_modules/errno": { "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "prr": "~1.0.1" @@ -10616,21 +13999,132 @@ }, "node_modules/error-ex": { "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, +<<<<<<< HEAD +======= + "node_modules/es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/es-module-lexer": { "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/es-set-tostringtag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, - "license": "MIT" + "dependencies": { + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/es-to-primitive": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -10687,58 +14181,24 @@ }, "node_modules/es6-promise": { "version": "4.2.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true }, "node_modules/es6-promisify": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "dev": true, - "license": "MIT", "dependencies": { "es6-promise": "^4.0.3" } }, - "node_modules/esbuild": { - "version": "0.17.8", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.8", - "@esbuild/android-arm64": "0.17.8", - "@esbuild/android-x64": "0.17.8", - "@esbuild/darwin-arm64": "0.17.8", - "@esbuild/darwin-x64": "0.17.8", - "@esbuild/freebsd-arm64": "0.17.8", - "@esbuild/freebsd-x64": "0.17.8", - "@esbuild/linux-arm": "0.17.8", - "@esbuild/linux-arm64": "0.17.8", - "@esbuild/linux-ia32": "0.17.8", - "@esbuild/linux-loong64": "0.17.8", - "@esbuild/linux-mips64el": "0.17.8", - "@esbuild/linux-ppc64": "0.17.8", - "@esbuild/linux-riscv64": "0.17.8", - "@esbuild/linux-s390x": "0.17.8", - "@esbuild/linux-x64": "0.17.8", - "@esbuild/netbsd-x64": "0.17.8", - "@esbuild/openbsd-x64": "0.17.8", - "@esbuild/sunos-x64": "0.17.8", - "@esbuild/win32-arm64": "0.17.8", - "@esbuild/win32-ia32": "0.17.8", - "@esbuild/win32-x64": "0.17.8" - } - }, "node_modules/esbuild-wasm": { "version": "0.17.8", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.8.tgz", + "integrity": "sha512-zCmpxv95E0FuCmvdw1K836UHnj4EdiQnFfjTby35y3LAjRPtXMj3sbHDRHjbD8Mqg5lTwq3knacr/1qIFU51CQ==", "dev": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -10748,29 +14208,37 @@ }, "node_modules/escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-html": { "version": "1.0.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true }, "node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/eslint": { +<<<<<<< HEAD "version": "8.52.0", +======= + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -10823,8 +14291,12 @@ }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -10833,8 +14305,9 @@ }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } @@ -10873,8 +14346,12 @@ }, "node_modules/eslint-module-utils": { "version": "2.8.0", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "debug": "^3.2.7" }, @@ -10889,16 +14366,18 @@ }, "node_modules/eslint-module-utils/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import": { "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", "dev": true, - "license": "MIT", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", @@ -10925,16 +14404,18 @@ }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -10944,16 +14425,18 @@ }, "node_modules/eslint-plugin-import/node_modules/semver": { "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.js" } }, "node_modules/eslint-plugin-jsdoc": { "version": "45.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-45.0.0.tgz", + "integrity": "sha512-l2+Jcs/Ps7oFA+SWY+0sweU/e5LgricnEl6EsDlyRTF5y0+NWL1y9Qwz9PHwHAxtdJq6lxPjEQWmYLMkvhzD4g==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@es-joy/jsdoccomment": "~0.39.4", "are-docs-informative": "^0.0.2", @@ -10973,8 +14456,9 @@ }, "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -10984,16 +14468,23 @@ }, "node_modules/eslint-plugin-prefer-arrow": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.3.tgz", + "integrity": "sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==", "dev": true, - "license": "MIT", "peerDependencies": { "eslint": ">=2.0.0" } }, "node_modules/eslint-plugin-unused-imports": { +<<<<<<< HEAD "version": "3.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz", "integrity": "sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==", +======= + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.0.0.tgz", + "integrity": "sha512-sduiswLJfZHeeBJ+MQaG+xYzSWdRXoSw61DpU13mzWumCkR0ufD0HmO4kdNokjrkluMHpj/7PJeN35pgbhW3kw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, "dependencies": { "eslint-rule-composer": "^0.3.0" @@ -11013,16 +14504,18 @@ }, "node_modules/eslint-rule-composer": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz", + "integrity": "sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==", "dev": true, - "license": "MIT", "engines": { "node": ">=4.0.0" } }, "node_modules/eslint-scope": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -11033,8 +14526,9 @@ }, "node_modules/eslint-utils": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, - "license": "MIT", "dependencies": { "eslint-visitor-keys": "^2.0.0" }, @@ -11050,16 +14544,18 @@ }, "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -11069,8 +14565,9 @@ }, "node_modules/eslint/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -11084,8 +14581,9 @@ }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -11098,13 +14596,20 @@ }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", +<<<<<<< HEAD "dev": true, "license": "Python-2.0" +======= + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -11118,8 +14623,9 @@ }, "node_modules/eslint/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -11129,8 +14635,9 @@ }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -11140,8 +14647,9 @@ }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -11155,16 +14663,23 @@ }, "node_modules/eslint/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/eslint/node_modules/find-up": { "version": "5.0.0", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -11178,8 +14693,9 @@ }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -11188,9 +14704,14 @@ } }, "node_modules/eslint/node_modules/globals": { +<<<<<<< HEAD "version": "13.21.0", +======= + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -11203,20 +14724,26 @@ }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/eslint/node_modules/is-path-inside": { - "version": "3.0.3", + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, +<<<<<<< HEAD "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", "dev": true, @@ -11237,12 +14764,64 @@ }, "engines": { "node": ">=8" +======= + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -11252,8 +14831,9 @@ }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -11263,8 +14843,9 @@ }, "node_modules/espree": { "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -11279,8 +14860,9 @@ }, "node_modules/esprima": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -11291,8 +14873,9 @@ }, "node_modules/esquery": { "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -11302,16 +14885,18 @@ }, "node_modules/esquery/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -11321,58 +14906,66 @@ }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/etag": { "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/eventemitter-asyncresource": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", + "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==", + "dev": true }, "node_modules/eventemitter3": { "version": "4.0.7", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true }, "node_modules/events": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/execa": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -11391,8 +14984,15 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, +<<<<<<< HEAD "node_modules/execa/node_modules/merge-stream": { "version": "2.0.0", +======= + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, "license": "MIT" }, @@ -11404,6 +15004,7 @@ "node": ">=6" } }, +<<<<<<< HEAD "node_modules/execa/node_modules/onetime": { "version": "5.1.2", "dev": true, @@ -11427,11 +15028,19 @@ "version": "3.1.1", "dev": true, "license": "Apache-2.0" +======= + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/express": { "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, - "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -11469,6 +15078,7 @@ "node": ">= 0.10.0" } }, +<<<<<<< HEAD "node_modules/express/node_modules/array-flatten": { "version": "1.1.1", "dev": true, @@ -11490,14 +15100,18 @@ "node": ">= 0.6" } }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/express/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, +<<<<<<< HEAD "node_modules/express/node_modules/finalhandler": { "version": "1.2.0", "dev": true, @@ -11587,6 +15201,13 @@ "engines": { "node": ">= 0.8" } +======= + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/express/node_modules/toidentifier": { "version": "1.0.1", @@ -11638,6 +15259,35 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, +<<<<<<< HEAD +======= + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/external-editor/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -11649,17 +15299,56 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, +<<<<<<< HEAD +======= + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" +<<<<<<< HEAD +======= + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/faye-websocket": { "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "dev": true, - "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -11667,10 +15356,29 @@ "node": ">=0.8.0" } }, +<<<<<<< HEAD +======= + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/file-entry-cache": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -11698,12 +15406,62 @@ }, "node_modules/file-saver-es": { "version": "2.0.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/file-saver-es/-/file-saver-es-2.0.5.tgz", + "integrity": "sha512-Kg0lt+is9nOyi/VDms9miScNGot25jVFbjFccXuCL/shd2Q+rt70MALxHVkXllsX83JEBLiHQNjDPGd/6FIOoQ==" + }, +<<<<<<< HEAD +======= + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "devOptional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "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", @@ -11716,11 +15474,18 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, +<<<<<<< HEAD "node_modules/find-cache-dir/node_modules/make-dir": { "version": "3.1.0", +======= + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "semver": "^6.0.0" }, "engines": { @@ -11740,16 +15505,35 @@ }, "node_modules/find-up": { "version": "4.1.0", +======= + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "locate-path": "^5.0.0", "path-exists": "^4.0.0" +======= + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">=8" } }, +<<<<<<< HEAD "node_modules/find-up/node_modules/locate-path": { "version": "5.0.0", "dev": true, @@ -11798,6 +15582,18 @@ "version": "1.15.5", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", +======= + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, "funding": [ { @@ -11816,16 +15612,18 @@ }, "node_modules/for-each": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } }, "node_modules/foreground-child": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, - "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -11839,8 +15637,12 @@ }, "node_modules/foreground-child/node_modules/signal-exit": { "version": "4.1.0", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "ISC", "engines": { "node": ">=14" }, @@ -11848,65 +15650,172 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, +<<<<<<< HEAD +======= + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, +<<<<<<< HEAD + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", +======= + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, "engines": { - "node": "*" + "node": ">=6 <7 || >=8" } }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "minipass": "^7.0.3" }, "engines": { - "node": ">= 0.12" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/forwarded": { - "version": "0.2.0", + "node_modules/fs-minipass/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/fresh": { - "version": "0.5.2", + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "license": "MIT", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.6" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/function-bind": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/functions-have-names": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gauge": { "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "dev": true, - "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", @@ -11921,14 +15830,21 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, +<<<<<<< HEAD "node_modules/gauge/node_modules/is-fullwidth-code-point": { "version": "3.0.0", +======= + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, +<<<<<<< HEAD "node_modules/gauge/node_modules/signal-exit": { "version": "3.0.7", "dev": true, @@ -11936,9 +15852,24 @@ }, "node_modules/gauge/node_modules/string-width": { "version": "4.2.3", +======= + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" @@ -11963,6 +15894,8 @@ "dev": true, "license": "MIT", "dependencies": { +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", @@ -11972,10 +15905,23 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD +======= + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/get-stream": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -11985,8 +15931,9 @@ }, "node_modules/get-symbol-description": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -11998,10 +15945,16 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/get-symbol-description/node_modules/call-bind": { "version": "1.0.5", +======= + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -12021,28 +15974,75 @@ } }, "node_modules/glob": { +<<<<<<< HEAD "version": "7.2.3", +======= + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", +<<<<<<< HEAD "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" +======= + "minimatch": "^5.0.1", + "once": "^1.3.0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, +<<<<<<< HEAD +======= + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "devOptional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/glob-to-regexp": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "BSD-2-Clause" + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } }, "node_modules/glob/node_modules/fs.realpath": { "version": "1.0.0", @@ -12086,16 +16086,18 @@ }, "node_modules/globals": { "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globalthis": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "license": "MIT", "dependencies": { "define-properties": "^1.1.3" }, @@ -12141,24 +16143,25 @@ } }, "node_modules/globby": { - "version": "11.1.0", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dev": true, - "license": "MIT", "dependencies": { - "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", "merge2": "^1.4.1", - "slash": "^3.0.0" + "slash": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, +<<<<<<< HEAD "node_modules/globby/node_modules/fast-glob": { "version": "3.3.1", "dev": true, @@ -12216,10 +16219,13 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/gopd": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -12227,15 +16233,34 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD +======= + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/graphemer": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/hammerjs": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz", + "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==", + "engines": { + "node": ">=0.8.0" + } }, "node_modules/handle-thing": { "version": "2.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true }, "node_modules/har-schema": { "version": "2.0.0", @@ -12276,29 +16301,86 @@ "url": "https://github.com/sponsors/epoberezkin" } }, +<<<<<<< HEAD +======= + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/has": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, +<<<<<<< HEAD +======= + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, - "license": "MIT", "dependencies": { - "function-bind": "^1.1.1" + "ansi-regex": "^2.0.0" }, "engines": { - "node": ">= 0.4.0" + "node": ">=0.10.0" } }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/has-bigints": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD +======= + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/has-proto": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12308,8 +16390,9 @@ }, "node_modules/has-symbols": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12317,15 +16400,54 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD +======= + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/has-unicode": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, - "license": "ISC" + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } }, +<<<<<<< HEAD "node_modules/hasown": { "version": "2.0.0", "dev": true, "license": "MIT", +======= + "node_modules/hdr-histogram-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hdr-histogram-js/-/hdr-histogram-js-2.0.3.tgz", + "integrity": "sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "function-bind": "^1.1.2" }, @@ -12333,10 +16455,20 @@ "node": ">= 0.4" } }, +<<<<<<< HEAD +======= + "node_modules/hdr-histogram-percentiles-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz", + "integrity": "sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/hosted-git-info": { "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^7.5.1" }, @@ -12344,10 +16476,23 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/hpack.js": { "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dev": true, - "license": "MIT", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -12377,8 +16522,9 @@ }, "node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12391,13 +16537,20 @@ }, "node_modules/hpack.js/node_modules/safe-buffer": { "version": "5.1.2", +<<<<<<< HEAD "dev": true, "license": "MIT" +======= + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -12409,6 +16562,8 @@ }, "node_modules/html-entities": { "version": "2.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", + "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", "dev": true, "funding": [ { @@ -12419,28 +16574,76 @@ "type": "patreon", "url": "https://patreon.com/mdevils" } - ], - "license": "MIT" + ] + }, +<<<<<<< HEAD +======= + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/http-cache-semantics": { "version": "4.1.1", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true }, "node_modules/http-deceiver": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, - "license": "MIT" + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/http-parser-js": { "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, - "license": "MIT" + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/http-proxy-agent": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, - "license": "MIT", "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -12452,8 +16655,9 @@ }, "node_modules/http-proxy-middleware": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dev": true, - "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -12473,10 +16677,16 @@ } } }, +<<<<<<< HEAD "node_modules/http-proxy-middleware/node_modules/@types/http-proxy": { "version": "1.17.12", +======= + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@types/node": "*" } @@ -12539,8 +16749,9 @@ }, "node_modules/https-proxy-agent": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "6", "debug": "4" @@ -12551,24 +16762,41 @@ }, "node_modules/human-signals": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/humanize-ms": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "dev": true, - "license": "MIT", "dependencies": { "ms": "^2.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/icss-utils": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "dev": true, - "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -12576,18 +16804,42 @@ "postcss": "^8.1.0" } }, +<<<<<<< HEAD +======= + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/ignore": { - "version": "5.2.4", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/ignore-walk": { - "version": "6.0.3", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.4.tgz", + "integrity": "sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==", "dev": true, - "license": "ISC", "dependencies": { "minimatch": "^9.0.0" }, @@ -12597,16 +16849,21 @@ }, "node_modules/ignore-walk/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/ignore-walk/node_modules/minimatch": { "version": "9.0.3", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -12619,8 +16876,9 @@ }, "node_modules/image-size": { "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "dev": true, - "license": "MIT", "optional": true, "bin": { "image-size": "bin/image-size.js" @@ -12629,10 +16887,26 @@ "node": ">=0.10.0" } }, +<<<<<<< HEAD +======= + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true + }, + "node_modules/immutable": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", + "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -12646,40 +16920,74 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=4" } }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/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" } }, +<<<<<<< HEAD +======= + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/ini": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.1.tgz", + "integrity": "sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==", "dev": true, - "license": "ISC", "engines": { "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/inquirer": { "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -12703,8 +17011,9 @@ }, "node_modules/inquirer/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -12717,8 +17026,9 @@ }, "node_modules/inquirer/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -12732,8 +17042,9 @@ }, "node_modules/inquirer/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -12770,8 +17081,9 @@ }, "node_modules/inquirer/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -12815,8 +17127,12 @@ }, "node_modules/inquirer/node_modules/rxjs": { "version": "7.8.1", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } @@ -12847,8 +17163,9 @@ }, "node_modules/inquirer/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, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -12856,6 +17173,7 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/inquirer/node_modules/through": { "version": "2.3.8", "dev": true, @@ -12863,15 +17181,27 @@ }, "node_modules/inquirer/node_modules/tmp": { "version": "0.0.33", +======= + "node_modules/internal-slot": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "os-tmpdir": "~1.0.2" +======= + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">=0.6.0" } }, +<<<<<<< HEAD "node_modules/inquirer/node_modules/wrap-ansi": { "version": "7.0.0", "dev": true, @@ -12881,6 +17211,12 @@ "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, +======= + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=10" }, @@ -12890,29 +17226,38 @@ }, "node_modules/ionicons": { "version": "6.1.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-6.1.3.tgz", + "integrity": "sha512-ptzz38dd/Yq+PgjhXegh7yhb/SLIk1bvL9vQDtLv1aoSc7alO6mX2DIMgcKYzt9vrNWkRu1f9Jr78zIFFyOXqw==", "dependencies": { "@stencil/core": "^2.18.0" } }, "node_modules/ip": { +<<<<<<< HEAD "version": "2.0.1", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", +======= + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true }, "node_modules/ipaddr.js": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/is-arguments": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -12924,11 +17269,18 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/is-arguments/node_modules/call-bind": { "version": "1.0.5", +======= + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", "set-function-length": "^1.1.1" @@ -12946,6 +17298,11 @@ }, "engines": { "node": ">= 0.4" +======= + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12953,13 +17310,58 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "license": "MIT" + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/is-callable": { "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -12968,20 +17370,44 @@ } }, "node_modules/is-core-module": { +<<<<<<< HEAD "version": "2.13.0", +======= + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +<<<<<<< HEAD +======= + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "license": "MIT", "dependencies": { - "has": "^1.0.3" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "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" }, @@ -12992,10 +17418,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, +<<<<<<< HEAD +======= + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "devOptional": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -13003,31 +17451,41 @@ "node": ">=0.10.0" } }, +<<<<<<< HEAD "node_modules/is-glob/node_modules/is-extglob": { "version": "2.1.1", "devOptional": true, "license": "MIT", +======= + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=0.10.0" } }, "node_modules/is-lambda": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true }, "node_modules/is-map": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-negative-zero": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -13035,10 +17493,80 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD +======= + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "devOptional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha512-cnS56eR9SPAscL77ik76ATVqoPARTqPIVkMDVxRaWH06zT+6+CzIroYRJ0VVvm0Z1zfAvxvz9i/D3Ppjaqt5Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-in-cwd/node_modules/is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/is-plain-obj": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -13048,8 +17576,9 @@ }, "node_modules/is-plain-object": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, - "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -13057,18 +17586,39 @@ "node": ">=0.10.0" } }, +<<<<<<< HEAD +======= + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/is-set": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -13089,35 +17639,100 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-stream": { - "version": "2.0.1", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, +<<<<<<< HEAD +======= + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, - "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.11" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true +<<<<<<< HEAD +======= + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/is-weakmap": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", "dev": true, - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakref": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -13140,8 +17755,9 @@ }, "node_modules/is-weakset": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -13165,13 +17781,15 @@ }, "node_modules/is-what": { "version": "3.14.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true }, "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" }, @@ -13179,10 +17797,38 @@ "node": ">=8" } }, +<<<<<<< HEAD +======= + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/isobject": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -13194,17 +17840,19 @@ "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -13218,16 +17866,21 @@ }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "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.js" } }, "node_modules/istanbul-lib-report": { "version": "3.0.1", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -13239,16 +17892,23 @@ }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "semver": "^7.5.3" }, @@ -13261,8 +17921,9 @@ }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -13272,8 +17933,9 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -13285,16 +17947,21 @@ }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-reports": { "version": "3.1.6", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -13303,24 +17970,136 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/istanbul-reports/node_modules/html-escaper": { "version": "2.0.2", "dev": true, "license": "MIT" +======= + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz", + "integrity": "sha512-KbdGQTf5jbZgltoHs31XGiChAPumMSY64OZMWLNYnEnMfG5uwGBhffePwuskexjT+/Jea/gU3qAU8344hNohSw==", + "dev": true, + "dependencies": { + "exit": "^0.1.2", + "glob": "^7.0.6", + "jasmine-core": "~2.8.0" + }, + "bin": { + "jasmine": "bin/jasmine.js" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/jasmine-core": { "version": "4.5.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.5.0.tgz", + "integrity": "sha512-9PMzyvhtocxb3aXJVOPqBDswdgyAeSB81QnLop4npOpbqnheaTEwPc9ZloQeVswugPManznQBjD8kWDTjlnHuw==", + "dev": true }, "node_modules/jasmine-spec-reporter": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-7.0.0.tgz", + "integrity": "sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "colors": "1.4.0" } }, +<<<<<<< HEAD +======= + "node_modules/jasmine/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jasmine/node_modules/jasmine-core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", + "integrity": "sha512-SNkOkS+/jMZvLhuSx1fjhcNWUC/KG6oVyFUGkSBEr9n1axSNduWU8GlI7suaHXr4yxjet6KjrUZxUTE5WzzWwQ==", + "dev": true + }, + "node_modules/jasminewd2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", + "integrity": "sha512-Rn0nZe4rfDhzA63Al3ZGh0E+JTmM6ESZYXJGKuqKGZObsAB9fwXPD03GjtIEvJBDOhN94T5MzbwZSqzFHSQPzg==", + "dev": true, + "engines": { + "node": ">= 6.9.x" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -13329,8 +18108,12 @@ }, "node_modules/js-yaml": { "version": "3.14.1", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -13347,16 +18130,18 @@ }, "node_modules/jsdoc-type-pratt-parser": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=12.0.0" } }, "node_modules/jsesc": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -13366,8 +18151,20 @@ }, "node_modules/json-buffer": { "version": "3.0.1", +<<<<<<< HEAD "dev": true, "license": "MIT" +======= + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/json-schema": { "version": "0.4.0", @@ -13376,15 +18173,22 @@ "dev": true }, "node_modules/json-schema-traverse": { +<<<<<<< HEAD "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true +======= + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", @@ -13393,6 +18197,7 @@ "dev": true }, "node_modules/json5": { +<<<<<<< HEAD "version": "1.0.2", "dev": true, "license": "MIT", @@ -13401,6 +18206,31 @@ }, "bin": { "json5": "lib/cli.js" +======= + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", + "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/json5/node_modules/minimist": { @@ -13417,11 +18247,12 @@ }, "node_modules/jsonparse": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, "engines": [ "node >= 0.2.0" - ], - "license": "MIT" + ] }, "node_modules/jsprim": { "version": "1.4.2", @@ -13440,8 +18271,9 @@ }, "node_modules/jszip": { "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, - "license": "(MIT OR GPL-3.0-or-later)", "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -13489,8 +18321,12 @@ }, "node_modules/jszip/node_modules/readable-stream": { "version": "2.3.8", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -13503,13 +18339,20 @@ }, "node_modules/jszip/node_modules/safe-buffer": { "version": "5.1.2", +<<<<<<< HEAD "dev": true, "license": "MIT" +======= + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/jszip/node_modules/string_decoder": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -13521,8 +18364,9 @@ }, "node_modules/karma": { "version": "6.4.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.2.tgz", + "integrity": "sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==", "dev": true, - "license": "MIT", "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -13558,8 +18402,9 @@ }, "node_modules/karma-chrome-launcher": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, - "license": "MIT", "dependencies": { "which": "^1.2.1" } @@ -13571,8 +18416,9 @@ }, "node_modules/karma-chrome-launcher/node_modules/which": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -13582,8 +18428,9 @@ }, "node_modules/karma-coverage": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", "dev": true, - "license": "MIT", "dependencies": { "istanbul-lib-coverage": "^3.2.0", "istanbul-lib-instrument": "^5.1.0", @@ -13598,8 +18445,9 @@ }, "node_modules/karma-coverage-istanbul-reporter": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-3.0.3.tgz", + "integrity": "sha512-wE4VFhG/QZv2Y4CdAYWDbMmcAHeS926ZIji4z+FkB2aF/EposRb6DP6G5ncT/wXhqUfAb/d7kZrNKPonbvsATw==", "dev": true, - "license": "MIT", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-report": "^3.0.0", @@ -13611,10 +18459,31 @@ "url": "https://github.com/sponsors/mattlewis92" } }, + "node_modules/karma-coverage-istanbul-reporter/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/karma-coverage-istanbul-reporter/node_modules/istanbul-lib-source-maps": { "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^2.0.5", @@ -13628,16 +18497,18 @@ }, "node_modules/karma-coverage-istanbul-reporter/node_modules/istanbul-lib-source-maps/node_modules/istanbul-lib-coverage": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=6" } }, "node_modules/karma-coverage-istanbul-reporter/node_modules/make-dir": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "license": "MIT", "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -13646,18 +18517,11 @@ "node": ">=6" } }, - "node_modules/karma-coverage-istanbul-reporter/node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/karma-coverage-istanbul-reporter/node_modules/rimraf": { "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -13667,24 +18531,27 @@ }, "node_modules/karma-coverage-istanbul-reporter/node_modules/semver": { "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/karma-coverage-istanbul-reporter/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/karma-jasmine": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", "dev": true, - "license": "MIT", "dependencies": { "jasmine-core": "^4.1.0" }, @@ -13696,9 +18563,14 @@ } }, "node_modules/karma-jasmine-html-reporter": { +<<<<<<< HEAD "version": "2.1.0", +======= + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.0.0.tgz", + "integrity": "sha512-SB8HNNiazAHXM1vGEzf8/tSyEhkfxuDdhYdPBX2Mwgzt0OuF2gicApQ+uvXLID/gXyJQgvrM9+1/2SxZFUUDIA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "peerDependencies": { "jasmine-core": "^4.0.0 || ^5.0.0", "karma": "^6.0.0", @@ -13707,17 +18579,25 @@ }, "node_modules/karma-source-map-support": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", "dev": true, - "license": "MIT", "dependencies": { "source-map-support": "^0.5.5" } }, +<<<<<<< HEAD "node_modules/karma/node_modules/@types/cors": { "version": "2.8.14", +======= + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "@types/node": "*" } }, @@ -13924,12 +18804,43 @@ "license": "MIT", "engines": { "node": ">= 0.6" +======= + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/karma/node_modules/mime": { "version": "2.6.0", +<<<<<<< HEAD "dev": true, "license": "MIT", +======= + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "bin": { "mime": "cli.js" }, @@ -13937,6 +18848,7 @@ "node": ">=4.0.0" } }, +<<<<<<< HEAD "node_modules/karma/node_modules/minimist": { "version": "1.2.8", "dev": true, @@ -13949,6 +18861,13 @@ "version": "0.5.6", "dev": true, "license": "MIT", +======= + "node_modules/karma/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "minimist": "^1.2.6" }, @@ -14056,12 +18975,14 @@ }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, +<<<<<<< HEAD "node_modules/karma/node_modules/statuses": { "version": "2.0.1", "dev": true, @@ -14111,6 +19032,13 @@ "version": "0.2.1", "dev": true, "license": "MIT", +======= + "node_modules/karma/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "rimraf": "^3.0.0" }, @@ -14118,6 +19046,7 @@ "node": ">=8.17.0" } }, +<<<<<<< HEAD "node_modules/karma/node_modules/toidentifier": { "version": "1.0.1", "dev": true, @@ -14180,10 +19109,13 @@ "node": ">=10" } }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/karma/node_modules/yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -14199,32 +19131,54 @@ }, "node_modules/karma/node_modules/yargs-parser": { "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/keyv": { +<<<<<<< HEAD "version": "4.5.3", "dev": true, "license": "MIT", +======= + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/kind-of": { "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, +<<<<<<< HEAD +======= + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", "dev": true, - "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/less": { "version": "4.1.3", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz", + "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -14248,8 +19202,9 @@ }, "node_modules/less-loader": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz", + "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", "dev": true, - "license": "MIT", "dependencies": { "klona": "^2.0.4" }, @@ -14281,8 +19236,9 @@ }, "node_modules/less/node_modules/make-dir": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { "pify": "^4.0.1", @@ -14292,31 +19248,11 @@ "node": ">=6" } }, - "node_modules/less/node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/less/node_modules/pify": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/less/node_modules/semver": { "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", "optional": true, "bin": { "semver": "bin/semver" @@ -14324,8 +19260,9 @@ }, "node_modules/less/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" @@ -14333,8 +19270,9 @@ }, "node_modules/levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -14364,8 +19302,9 @@ }, "node_modules/license-webpack-plugin": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", "dev": true, - "license": "ISC", "dependencies": { "webpack-sources": "^3.0.0" }, @@ -14378,97 +19317,475 @@ } } }, +<<<<<<< HEAD "node_modules/license-webpack-plugin/node_modules/webpack-sources": { "version": "3.2.3", "dev": true, "license": "MIT", "engines": { "node": ">=10.13.0" +======= + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "dependencies": { + "immediate": "~3.0.5" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/lines-and-columns": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=6.11.5" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/loader-utils": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true, - "license": "MIT", "engines": { - "node": ">= 12.13.0" + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, +<<<<<<< HEAD +======= + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, +<<<<<<< HEAD + "node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" +======= + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + } + }, + "node_modules/magic-string": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.29.0.tgz", + "integrity": "sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, +<<<<<<< HEAD + "node_modules/magic-string/node_modules/sourcemap-codec": { + "version": "1.4.8", + "dev": true, + "license": "MIT" +======= + "node_modules/make-dir": { + "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, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-fetch-happen/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/locate-path": { - "version": "6.0.0", + "node_modules/make-fetch-happen/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", "dev": true, - "license": "MIT", "dependencies": { - "p-locate": "^5.0.0" + "unique-slug": "^3.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/lodash-es": { - "version": "4.17.21", - "license": "MIT" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", + "node_modules/make-fetch-happen/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", "dev": true, - "license": "MIT" + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "dev": true, - "license": "MIT" + "node_modules/make-fetch-happen/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, - "node_modules/lru-cache": { - "version": "7.18.3", + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, - "license": "ISC", "engines": { - "node": ">=12" + "node": ">= 0.6" } }, - "node_modules/magic-string": { - "version": "0.26.2", + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, - "license": "MIT", "dependencies": { - "sourcemap-codec": "^1.4.8" + "fs-monkey": "^1.0.4" }, "engines": { - "node": ">=12" + "node": ">= 4.0.0" } }, - "node_modules/magic-string/node_modules/sourcemap-codec": { - "version": "1.4.8", - "dev": true, - "license": "MIT" - }, - "node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" - }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/merge-descriptors": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT" + "engines": { + "node": ">= 8" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/methods": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, +<<<<<<< HEAD +======= + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -14490,10 +19807,22 @@ "node": ">= 0.6" } }, +<<<<<<< HEAD +======= + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/mini-css-extract-plugin": { "version": "2.7.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz", + "integrity": "sha512-EdlUizq13o0Pd+uCp+WO/JpkLvHRVGt97RqfeGhXqAcorYo1ypJSpkV+WDT0vY/kmh/p7wRdJNJtuyK540PXDw==", "dev": true, - "license": "MIT", "dependencies": { "schema-utils": "^4.0.0" }, @@ -14533,13 +19862,15 @@ }, "node_modules/minimalistic-assert": { "version": "1.0.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true }, "node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14547,10 +19878,32 @@ "node": "*" } }, +<<<<<<< HEAD +======= + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/minipass-collect": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -14560,8 +19913,46 @@ }, "node_modules/minipass-collect/node_modules/minipass": { "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, +<<<<<<< HEAD +======= + "node_modules/minipass-collect/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14569,10 +19960,18 @@ "node": ">=8" } }, + "node_modules/minipass-fetch/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/minipass-flush": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -14582,8 +19981,9 @@ }, "node_modules/minipass-flush/node_modules/minipass": { "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14591,10 +19991,17 @@ "node": ">=8" } }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/minipass-json-stream": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", "dev": true, - "license": "MIT", "dependencies": { "jsonparse": "^1.3.1", "minipass": "^3.0.0" @@ -14602,8 +20009,9 @@ }, "node_modules/minipass-json-stream/node_modules/minipass": { "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14611,10 +20019,17 @@ "node": ">=8" } }, + "node_modules/minipass-json-stream/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/minipass-pipeline": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -14624,8 +20039,9 @@ }, "node_modules/minipass-pipeline/node_modules/minipass": { "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14633,10 +20049,17 @@ "node": ">=8" } }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/minipass-sized": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -14646,8 +20069,9 @@ }, "node_modules/minipass-sized/node_modules/minipass": { "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14655,10 +20079,17 @@ "node": ">=8" } }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/minizlib": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -14669,8 +20100,9 @@ }, "node_modules/minizlib/node_modules/minipass": { "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14678,10 +20110,17 @@ "node": ">=8" } }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/mkdirp": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -14689,22 +20128,17 @@ "node": ">=10" } }, - "node_modules/moment": { - "version": "2.29.4", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/multicast-dns": { "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dev": true, - "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -14713,12 +20147,34 @@ "multicast-dns": "cli.js" } }, +<<<<<<< HEAD "node_modules/multicast-dns/node_modules/dns-packet": { "version": "5.6.1", "dev": true, "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" +======= + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">=6" @@ -14726,16 +20182,26 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/needle": { - "version": "3.2.0", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { - "debug": "^3.2.6", "iconv-lite": "^0.6.3", "sax": "^1.2.4" }, @@ -14746,6 +20212,7 @@ "node": ">= 4.4.x" } }, +<<<<<<< HEAD "node_modules/needle/node_modules/debug": { "version": "3.2.7", "dev": true, @@ -14767,32 +20234,46 @@ "node": ">=0.10.0" } }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/negotiator": { "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, +<<<<<<< HEAD +======= + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/ng2-charts": { - "version": "2.4.3", - "license": "ISC", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-4.1.1.tgz", + "integrity": "sha512-iHwXDbmX86lfeH8VRcsaW2tJATsuAZo4kvvC/Yk2l35zOHjevja1qBvO6BAibiDazi9r9aS6ZRJOqWPsz1pP2w==", "dependencies": { - "@types/chart.js": "^2.9.24", "lodash-es": "^4.17.15", - "tslib": "^2.0.0" + "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/common": ">=7.2.0", - "@angular/core": ">=7.2.0", - "chart.js": "^2.9.3", - "rxjs": "^6.3.3" + "@angular/cdk": ">=14.0.0", + "@angular/common": ">=14.0.0", + "@angular/core": ">=14.0.0", + "chart.js": "^3.4.0 || ^4.0.0", + "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/ngx-cookie-service": { "version": "15.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-15.0.0.tgz", + "integrity": "sha512-KU1JCjfpDTvD6L0FhHN9W/oP3Sue8yMAAK6XY3h/MEhrPS7vx6t3+h0ulY8l8R/9d1cmlQVyTHn1Jd1Jdf5K+g==", "dependencies": { "tslib": "^2.0.0" }, @@ -14801,34 +20282,122 @@ "@angular/core": "^15.0.0" } }, - "node_modules/ngx-spinner": { - "version": "15.0.1", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/common": "^15.0.0", - "@angular/core": "^15.0.0" + "node_modules/ngx-spinner": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/ngx-spinner/-/ngx-spinner-15.0.1.tgz", + "integrity": "sha512-7DjETmBpuXTwI68ad1xMKpwt4Cyz1eyu8E7AJcFiKa+8JAnbo0k1qfvWur0aemncRNxDxHoyl6jw42MsnE/B+g==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^15.0.0", + "@angular/core": "^15.0.0" + } + }, + "node_modules/nice-napi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", + "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "!win32" + ], + "dependencies": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2" + } + }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true, + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, +<<<<<<< HEAD + "node_modules/node-releases": { + "version": "2.0.13", +======= + "node_modules/node-gyp": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" } }, - "node_modules/node-forge": { - "version": "1.3.1", + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">= 6.13.0" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/node-releases": { - "version": "2.0.13", - "dev": true, - "license": "MIT" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true }, "node_modules/nopt": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", "dev": true, - "license": "ISC", "dependencies": { "abbrev": "^1.0.0" }, @@ -14841,8 +20410,9 @@ }, "node_modules/normalize-package-data": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", + "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^6.0.0", "is-core-module": "^2.8.1", @@ -14853,18 +20423,32 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/normalize-range": { "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/npm-bundled": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz", + "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==", "dev": true, - "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^3.0.0" }, @@ -14872,18 +20456,35 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/npm-normalize-package-bin": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm-package-arg": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", "dev": true, - "license": "ISC", "dependencies": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", @@ -14896,8 +20497,9 @@ }, "node_modules/npm-packlist": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", + "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", "dev": true, - "license": "ISC", "dependencies": { "ignore-walk": "^6.0.0" }, @@ -14907,8 +20509,9 @@ }, "node_modules/npm-pick-manifest": { "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz", + "integrity": "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==", "dev": true, - "license": "ISC", "dependencies": { "npm-install-checks": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -14932,8 +20535,9 @@ }, "node_modules/npm-registry-fetch": { "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", "dev": true, - "license": "ISC", "dependencies": { "make-fetch-happen": "^11.0.0", "minipass": "^5.0.0", @@ -14947,10 +20551,23 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", "dev": true, - "license": "ISC", "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^17.0.0", @@ -14974,16 +20591,21 @@ }, "node_modules/npm-registry-fetch/node_modules/minipass": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=8" } }, "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { "version": "3.0.4", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -14997,17 +20619,25 @@ } }, "node_modules/npm-registry-fetch/node_modules/minipass-fetch/node_modules/minipass": { +<<<<<<< HEAD "version": "7.0.3", "dev": true, "license": "ISC", +======= + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/npm-run-path": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -15025,8 +20655,9 @@ }, "node_modules/npmlog": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", "dev": true, - "license": "ISC", "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", @@ -15037,10 +20668,24 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, +<<<<<<< HEAD "node_modules/npmlog/node_modules/set-blocking": { "version": "2.0.0", "dev": true, "license": "ISC" +======= + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/oauth-sign": { "version": "0.9.0", @@ -15053,16 +20698,30 @@ }, "node_modules/object-assign": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, +<<<<<<< HEAD +======= + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/object-is": { "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -15115,19 +20774,21 @@ }, "node_modules/object-is/node_modules/object-keys": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { - "version": "4.1.4", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -15187,6 +20848,7 @@ }, "node_modules/object.values": { "version": "1.1.7", +<<<<<<< HEAD "dev": true, "license": "MIT", "dependencies": { @@ -15296,11 +20958,15 @@ }, "node_modules/object.values/node_modules/function.prototype.name": { "version": "1.1.6", +======= + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", +<<<<<<< HEAD "es-abstract": "^1.22.1", "functions-have-names": "^1.2.3" }, @@ -15486,6 +21152,9 @@ "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" +======= + "es-abstract": "^1.22.1" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">= 0.4" @@ -15496,21 +21165,65 @@ }, "node_modules/obuf": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, - "license": "MIT" + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/on-headers": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.8" } }, +<<<<<<< HEAD +======= + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/open": { "version": "8.4.1", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.1.tgz", + "integrity": "sha512-/4b7qZNhv6Uhd7jjnREh1NjnPxlTq+XNWPG88Ydkj5AILcA5m3ajvcg57pB24EQjKv0dK62XnDqk9c/hkIG5Kg==", "dev": true, - "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -15525,8 +21238,9 @@ }, "node_modules/optionator": { "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, - "license": "MIT", "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -15565,7 +21279,8 @@ }, "node_modules/ora": { "version": "5.4.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -15586,7 +21301,8 @@ }, "node_modules/ora/node_modules/ansi-styles": { "version": "4.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, @@ -15599,7 +21315,8 @@ }, "node_modules/ora/node_modules/chalk": { "version": "4.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -15623,7 +21340,8 @@ }, "node_modules/ora/node_modules/color-convert": { "version": "2.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { "color-name": "~1.1.4" }, @@ -15643,7 +21361,8 @@ }, "node_modules/ora/node_modules/has-flag": { "version": "4.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" } @@ -15691,7 +21410,8 @@ }, "node_modules/ora/node_modules/supports-color": { "version": "7.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, @@ -15715,6 +21435,7 @@ "node": ">=0.10.0" } }, +<<<<<<< HEAD "node_modules/p-locate": { "version": "5.0.0", "dev": true, @@ -15731,33 +21452,47 @@ }, "node_modules/p-locate/node_modules/p-limit": { "version": "3.1.0", +======= + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { - "yocto-queue": "^0.1.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, +<<<<<<< HEAD "node_modules/p-locate/node_modules/yocto-queue": { "version": "0.1.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" +======= + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "engines": { + "node": ">=8" } }, "node_modules/p-map": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, - "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -15770,8 +21505,9 @@ }, "node_modules/p-retry": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" @@ -15780,18 +21516,29 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/p-retry/node_modules/retry": { "version": "0.13.1", "dev": true, "license": "MIT", "engines": { "node": ">= 4" +======= + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/pacote": { "version": "15.1.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.1.0.tgz", + "integrity": "sha512-FFcjtIl+BQNfeliSm7MZz5cpdohvUV1yjGnqgVM4UnVF7JslRY0ImXAygdaCDV0jjUADEWu4y5xsDV8brtrTLg==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/git": "^4.0.0", "@npmcli/installed-package-contents": "^2.0.1", @@ -15819,6 +21566,7 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD "node_modules/pacote/node_modules/@npmcli/git": { "version": "4.1.0", "dev": true, @@ -16086,11 +21834,19 @@ "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } +======= + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -16100,8 +21856,9 @@ }, "node_modules/parse-json": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -16122,16 +21879,27 @@ }, "node_modules/parse-node-version": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.10" } }, +<<<<<<< HEAD +======= + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/parse5-html-rewriting-stream": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", "dev": true, - "license": "MIT", "dependencies": { "entities": "^4.3.0", "parse5": "^7.0.0", @@ -16143,8 +21911,9 @@ }, "node_modules/parse5-html-rewriting-stream/node_modules/entities": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -16154,8 +21923,9 @@ }, "node_modules/parse5-html-rewriting-stream/node_modules/parse5": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, - "license": "MIT", "dependencies": { "entities": "^4.4.0" }, @@ -16163,10 +21933,23 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, +<<<<<<< HEAD +======= + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/parse5-sax-parser": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", "dev": true, - "license": "MIT", "dependencies": { "parse5": "^7.0.0" }, @@ -16176,8 +21959,9 @@ }, "node_modules/parse5-sax-parser/node_modules/entities": { "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -16187,8 +21971,9 @@ }, "node_modules/parse5-sax-parser/node_modules/parse5": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, - "license": "MIT", "dependencies": { "entities": "^4.4.0" }, @@ -16196,37 +21981,165 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, +<<<<<<< HEAD +======= + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, +<<<<<<< HEAD +======= + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/path-to-regexp": { "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=8" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true +<<<<<<< HEAD +======= + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "devOptional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/pify": { - "version": "2.3.0", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, +<<<<<<< HEAD +======= + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/pinkie-promise": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, - "license": "MIT", "dependencies": { "pinkie": "^2.0.0" }, @@ -16244,8 +22157,9 @@ }, "node_modules/piscina": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-3.2.0.tgz", + "integrity": "sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==", "dev": true, - "license": "MIT", "dependencies": { "eventemitter-asyncresource": "^1.0.0", "hdr-histogram-js": "^2.0.1", @@ -16308,8 +22222,9 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, - "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -16319,6 +22234,8 @@ }, "node_modules/postcss": { "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", "dev": true, "funding": [ { @@ -16330,7 +22247,6 @@ "url": "https://tidelift.com/funding/github/npm/postcss" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -16342,8 +22258,9 @@ }, "node_modules/postcss-loader": { "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.0.2.tgz", + "integrity": "sha512-fUJzV/QH7NXUAqV8dWJ9Lg4aTkDCezpTS5HgJ2DvqznexTbSTxgi/dTECvTZ15BwKTtk8G/bqI/QTu2HPd3ZCg==", "dev": true, - "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.0", "klona": "^2.0.5", @@ -16371,8 +22288,9 @@ }, "node_modules/postcss-modules-extract-imports": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", "dev": true, - "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -16380,10 +22298,31 @@ "postcss": "^8.1.0" } }, +<<<<<<< HEAD +======= + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", + "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/postcss-modules-scope": { - "version": "3.0.0", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.0.tgz", + "integrity": "sha512-SaIbK8XW+MZbd0xHPf7kdfA/3eOt7vxJ72IRecn3EzuZVLr1r0orzf0MX/pN8m+NMDoo6X/SQd8oeKqGZd8PXg==", "dev": true, - "license": "ISC", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -16413,8 +22352,9 @@ }, "node_modules/postcss-modules-values": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "dev": true, - "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" }, @@ -16425,11 +22365,29 @@ "postcss": "^8.1.0" } }, +<<<<<<< HEAD +======= + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/postcss-value-parser": { "version": "4.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, +<<<<<<< HEAD "node_modules/postcss/node_modules/nanoid": { "version": "3.3.6", "dev": true, @@ -16443,10 +22401,18 @@ "bin": { "nanoid": "bin/nanoid.cjs" }, +======= + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, +<<<<<<< HEAD "node_modules/postcss/node_modules/picocolors": { "version": "1.0.0", "dev": true, @@ -16456,27 +22422,46 @@ "version": "1.0.2", "dev": true, "license": "BSD-3-Clause", +======= + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=0.10.0" } }, "node_modules/proc-log": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/promise-inflight": { "version": "1.0.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true }, "node_modules/promise-retry": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, - "license": "MIT", "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -16485,10 +22470,21 @@ "node": ">=10" } }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/protractor": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/protractor/-/protractor-7.0.0.tgz", + "integrity": "sha512-UqkFjivi4GcvUQYzqGYNe0mLzfn5jiLmO8w9nMhQoJRLhy2grJonpga2IWhI6yJO30LibWXJJtA4MOIZD2GgZw==", + "deprecated": "We have news to share - Protractor is deprecated and will reach end-of-life by Summer 2023. To learn more and find out about other options please refer to this post on the Angular blog. Thank you for using and contributing to Protractor. https://goo.gle/state-of-e2e-in-angular", "dev": true, - "license": "MIT", "dependencies": { "@types/q": "^0.0.32", "@types/selenium-webdriver": "^3.0.0", @@ -16527,24 +22523,27 @@ }, "node_modules/protractor/node_modules/ansi-regex": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/protractor/node_modules/ansi-styles": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/protractor/node_modules/chalk": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -16558,8 +22557,9 @@ }, "node_modules/protractor/node_modules/cliui": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -16568,16 +22568,18 @@ }, "node_modules/protractor/node_modules/cliui/node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/protractor/node_modules/cliui/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" }, @@ -16587,8 +22589,9 @@ }, "node_modules/protractor/node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -16596,11 +22599,18 @@ "node": ">=7.0.0" } }, +<<<<<<< HEAD "node_modules/protractor/node_modules/debug": { "version": "3.2.7", +======= + "node_modules/protractor/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "ms": "^2.1.1" } }, @@ -16706,6 +22716,47 @@ }, "engines": { "node": "*" +======= + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/protractor/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/protractor/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/protractor/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/protractor/node_modules/set-blocking": { @@ -16715,16 +22766,18 @@ }, "node_modules/protractor/node_modules/source-map": { "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/protractor/node_modules/source-map-support": { "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, - "license": "MIT", "dependencies": { "source-map": "^0.5.6" } @@ -16763,8 +22816,9 @@ }, "node_modules/protractor/node_modules/strip-ansi": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -16774,21 +22828,50 @@ }, "node_modules/protractor/node_modules/supports-color": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, +<<<<<<< HEAD "node_modules/protractor/node_modules/which-module": { "version": "2.0.1", "dev": true, "license": "ISC" +======= + "node_modules/protractor/node_modules/webdriver-manager": { + "version": "12.1.9", + "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.9.tgz", + "integrity": "sha512-Yl113uKm8z4m/KMUVWHq1Sjtla2uxEBtx2Ue3AmIlnlPAKloDn/Lvmy6pqWCUersVISpdMeVpAaGbNnvMuT2LQ==", + "dev": true, + "dependencies": { + "adm-zip": "^0.5.2", + "chalk": "^1.1.1", + "del": "^2.2.0", + "glob": "^7.0.3", + "ini": "^1.3.4", + "minimist": "^1.2.0", + "q": "^1.4.1", + "request": "^2.87.0", + "rimraf": "^2.5.2", + "semver": "^5.3.0", + "xml2js": "^0.4.17" + }, + "bin": { + "webdriver-manager": "bin/webdriver-manager" + }, + "engines": { + "node": ">=6.9.x" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/protractor/node_modules/wrap-ansi": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -16800,16 +22883,18 @@ }, "node_modules/protractor/node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/protractor/node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -16822,8 +22907,9 @@ }, "node_modules/protractor/node_modules/wrap-ansi/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" }, @@ -16833,13 +22919,15 @@ }, "node_modules/protractor/node_modules/y18n": { "version": "4.0.3", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true }, "node_modules/protractor/node_modules/yargs": { "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -16859,8 +22947,9 @@ }, "node_modules/protractor/node_modules/yargs-parser": { "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, - "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -16871,8 +22960,9 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, - "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -16883,16 +22973,18 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/prr": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/psl": { @@ -16902,17 +22994,46 @@ "dev": true }, "node_modules/punycode": { +<<<<<<< HEAD "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", +======= + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=6" } }, +<<<<<<< HEAD +======= + "node_modules/q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "engines": { + "node": ">=0.9" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/qs": { "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -16923,84 +23044,334 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/qs/node_modules/call-bind": { "version": "1.0.5", +======= + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "dependencies": { +<<<<<<< HEAD + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" +======= + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +<<<<<<< HEAD + "node_modules/qs/node_modules/object-inspect": { + "version": "1.12.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/qs/node_modules/side-channel": { + "version": "1.0.4", +======= + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, +<<<<<<< HEAD + "funding": { + "url": "https://github.com/sponsors/ljharb" +======= + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-package-json": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", + "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", + "dev": true, + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, +<<<<<<< HEAD +======= + "node_modules/read-package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/read-package-json/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, - "license": "MIT", "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "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" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/qs/node_modules/object-inspect": { - "version": "1.12.3", + "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/qs/node_modules/side-channel": { - "version": "1.0.4", + "node_modules/read-package-json/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/read-package-json-fast": { - "version": "3.0.2", + "node_modules/read-package-json/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, - "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 6" } }, - "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", - "dev": true, - "license": "MIT", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "devOptional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8.10.0" } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/reflect-metadata": { - "version": "0.1.13", - "dev": true, - "license": "Apache-2.0" + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", + "dev": true }, "node_modules/regenerate": { "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, +<<<<<<< HEAD + "node_modules/regenerator-runtime": { + "version": "0.13.11", "dev": true, "license": "MIT" +======= + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } }, "node_modules/regenerator-runtime": { "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, - "license": "MIT" + "dependencies": { + "@babel/runtime": "^7.8.4" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/regex-parser": { - "version": "2.2.11", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, - "license": "MIT" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "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" + }, + "engines": { + "node": ">=4" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/regjsparser": { "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" }, @@ -17010,6 +23381,8 @@ }, "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, "bin": { "jsesc": "bin/jsesc" @@ -17066,12 +23439,45 @@ "uuid": "bin/uuid" } }, +<<<<<<< HEAD +======= + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/resolve": { - "version": "1.22.1", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "license": "MIT", "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -17084,16 +23490,21 @@ }, "node_modules/resolve-from": { "version": "5.0.0", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/resolve-url-loader": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", "dev": true, - "license": "MIT", "dependencies": { "adjust-sourcemap-loader": "^4.0.0", "convert-source-map": "^1.7.0", @@ -17123,8 +23534,9 @@ }, "node_modules/resolve-url-loader/node_modules/loader-utils": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, - "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -17136,12 +23548,14 @@ }, "node_modules/resolve-url-loader/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, +<<<<<<< HEAD "node_modules/resolve/node_modules/path-parse": { "version": "1.0.7", "dev": true, @@ -17151,6 +23565,16 @@ "version": "1.0.0", "dev": true, "license": "MIT", +======= + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">= 0.4" }, @@ -17159,17 +23583,38 @@ } }, "node_modules/retry": { - "version": "0.12.0", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 4" } }, +<<<<<<< HEAD +======= + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -17180,13 +23625,80 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/roboto-fontface": { "version": "0.10.0", - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz", + "integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g==" + }, +<<<<<<< HEAD +======= + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/rxjs": { "version": "6.6.7", - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dependencies": { "tslib": "^1.9.0" }, @@ -17196,9 +23708,11 @@ }, "node_modules/rxjs/node_modules/tslib": { "version": "1.14.1", - "license": "0BSD" + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/safe-array-concat": { +<<<<<<< HEAD "version": "1.0.0", "dev": true, "license": "MIT", @@ -17256,11 +23770,64 @@ "version": "1.0.0", "dev": true, "license": "MIT", +======= + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.1.tgz", + "integrity": "sha512-Y5NejJTTliTyY4H7sipGqY+RX5P87i3F7c4Rcepy72nq+mNLhIsD0W4c7kEmduMDQCSqtPsXPlSTsFhh2LQv+g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", "is-regex": "^1.1.4" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -17314,8 +23881,9 @@ }, "node_modules/sass": { "version": "1.58.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.1.tgz", + "integrity": "sha512-bnINi6nPXbP1XNRaranMFEBZWUfdW/AF16Ql5+ypRxfTvCRTTKrLsMIakyDcayUt2t/RZotmL4kgJwNH5xO+bg==", "dev": true, - "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -17330,8 +23898,9 @@ }, "node_modules/sass-loader": { "version": "13.2.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.2.0.tgz", + "integrity": "sha512-JWEp48djQA4nbZxmgC02/Wh0eroSUutulROUusYJO9P9zltRbNN80JCBHqRGzjd4cmZCa/r88xgfkjGD0TXsHg==", "dev": true, - "license": "MIT", "dependencies": { "klona": "^2.0.4", "neo-async": "^2.6.2" @@ -17365,14 +23934,38 @@ } } }, +<<<<<<< HEAD "node_modules/sass-loader/node_modules/klona": { "version": "2.0.6", "dev": true, "license": "MIT", +======= + "node_modules/saucelabs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", + "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "dev": true, + "dependencies": { + "https-proxy-agent": "^2.2.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/saucelabs/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dev": true, + "dependencies": { + "es6-promisify": "^5.0.0" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">= 8" } }, +<<<<<<< HEAD "node_modules/sass-loader/node_modules/neo-async": { "version": "2.6.2", "dev": true, @@ -17387,6 +23980,26 @@ "version": "1.0.2", "dev": true, "license": "BSD-3-Clause", +======= + "node_modules/saucelabs/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/saucelabs/node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dev": true, + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=0.10.0" } @@ -17396,11 +24009,34 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", "dev": true +<<<<<<< HEAD +======= + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/select-hose": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true }, "node_modules/selenium-webdriver": { "version": "3.6.0", @@ -17417,6 +24053,26 @@ "node": ">= 6.9.0" } }, + "node_modules/selenium-webdriver/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/selenium-webdriver/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -17429,10 +24085,41 @@ "rimraf": "bin.js" } }, +<<<<<<< HEAD "node_modules/semver": { "version": "7.5.3", +======= + "node_modules/selenium-webdriver/node_modules/tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha512-HXdTB7lvMwcb55XFfrTM8CPr/IYREk4hVBFaQ4b/6nInrluSL86hfHm7vu0luYKCfyBZp2trCjpc8caC3vVM3w==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -17445,8 +24132,14 @@ }, "node_modules/semver/node_modules/lru-cache": { "version": "6.0.0", +<<<<<<< HEAD "dev": true, "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "yallist": "^4.0.0" }, @@ -17454,10 +24147,20 @@ "node": ">=10" } }, +<<<<<<< HEAD +======= + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/send": { "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, - "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -17479,14 +24182,16 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", +<<<<<<< HEAD "dev": true, "license": "MIT" }, @@ -17564,12 +24269,32 @@ "license": "MIT", "engines": { "node": ">=0.6" +======= + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/serve-index": { "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dev": true, - "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -17585,24 +24310,27 @@ }, "node_modules/serve-index/node_modules/debug": { "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/serve-index/node_modules/depd": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dev": true, - "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -17615,13 +24343,15 @@ }, "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, "node_modules/serve-index/node_modules/parseurl": { "version": "1.3.3", @@ -17633,8 +24363,18 @@ }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, - "license": "ISC" + "engines": { + "node": ">= 0.6" + } }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", @@ -17646,8 +24386,9 @@ }, "node_modules/serve-static": { "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, - "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -17655,87 +24396,326 @@ "send": "0.18.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8.0" + } + }, +<<<<<<< HEAD + "node_modules/serve-static/node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "dev": true, + "license": "MIT", +======= + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, +<<<<<<< HEAD + "node_modules/set-function-length/node_modules/has-property-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" +======= + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, +<<<<<<< HEAD + "node_modules/slash": { + "version": "3.0.0", +======= + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sigstore": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-1.9.0.tgz", + "integrity": "sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^1.1.0", + "@sigstore/protobuf-specs": "^0.2.0", + "@sigstore/sign": "^1.0.0", + "@sigstore/tuf": "^1.0.3", + "make-fetch-happen": "^11.0.1" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/sigstore/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/serve-static/node_modules/parseurl": { - "version": "1.3.3", + "node_modules/sigstore/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "node_modules/set-function-length": { - "version": "1.1.1", + "node_modules/sigstore/node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", "dev": true, - "license": "MIT", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" }, "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-length/node_modules/has-property-descriptors": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.2" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", + "node_modules/sigstore/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/slash": { - "version": "3.0.0", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/smart-buffer": { "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/socket.io": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.3.tgz", + "integrity": "sha512-SE+UIQXBQE+GPG2oszWMlsEmWtHVqw/h1VrYJGK5/MC7CH5p58N448HwIrtREcvR4jfdOJAY4ieQfxMr55qbbw==", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/socket.io-adapter": { "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", "dev": true, - "license": "MIT", "dependencies": { "ws": "~8.11.0" } }, +<<<<<<< HEAD +======= + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/sockjs": { "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "dev": true, - "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -17744,16 +24724,18 @@ }, "node_modules/sockjs/node_modules/uuid": { "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, - "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/socks": { "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, - "license": "MIT", "dependencies": { "ip": "^2.0.0", "smart-buffer": "^4.2.0" @@ -17765,8 +24747,9 @@ }, "node_modules/socks-proxy-agent": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -17778,16 +24761,30 @@ }, "node_modules/source-map": { "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, +<<<<<<< HEAD +======= + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/source-map-loader": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-4.0.1.tgz", + "integrity": "sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==", "dev": true, - "license": "MIT", "dependencies": { "abab": "^2.0.6", "iconv-lite": "^0.6.3", @@ -17825,8 +24822,9 @@ }, "node_modules/source-map-support": { "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, - "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -17834,35 +24832,56 @@ }, "node_modules/source-map-support/node_modules/source-map": { "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, +<<<<<<< HEAD +======= + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/spdx-correct": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, +<<<<<<< HEAD "node_modules/spdx-correct/node_modules/spdx-license-ids": { "version": "3.0.13", "dev": true, "license": "CC0-1.0" +======= + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/spdx-expression-parse": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, +<<<<<<< HEAD "node_modules/spdx-expression-parse/node_modules/spdx-exceptions": { "version": "2.3.0", "dev": true, @@ -17872,11 +24891,19 @@ "version": "3.0.13", "dev": true, "license": "CC0-1.0" +======= + "node_modules/spdx-license-ids": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/spdy": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -17890,8 +24917,9 @@ }, "node_modules/spdy-transport": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -17901,6 +24929,7 @@ "wbuf": "^1.7.3" } }, +<<<<<<< HEAD "node_modules/spdy-transport/node_modules/inherits": { "version": "2.0.4", "dev": true, @@ -17908,8 +24937,19 @@ }, "node_modules/spdy-transport/node_modules/readable-stream": { "version": "3.6.2", +======= + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -17959,8 +24999,12 @@ }, "node_modules/ssri": { "version": "10.0.5", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", + "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -17969,6 +25013,7 @@ } }, "node_modules/ssri/node_modules/minipass": { +<<<<<<< HEAD "version": "7.0.3", "dev": true, "license": "ISC", @@ -17978,19 +25023,92 @@ }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", +======= + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dev": true, + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "internal-slot": "^1.0.4" +======= + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "engines": { "node": ">= 0.4" } }, +<<<<<<< HEAD "node_modules/stop-iteration-iterator/node_modules/call-bind": { "version": "1.0.5", +======= + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "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==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -18034,20 +25152,24 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, - "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -18395,6 +25517,40 @@ "version": "6.0.1", "dev": true, "license": "MIT", +======= + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "ansi-regex": "^5.0.1" }, @@ -18402,10 +25558,16 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/strip-ansi/node_modules/ansi-regex": { "version": "6.0.1", +======= + "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==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -18415,16 +25577,18 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -18432,18 +25596,61 @@ "url": "https://github.com/sponsors/sindresorhus" } }, +<<<<<<< HEAD +======= + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/symbol-observable": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, +<<<<<<< HEAD + "node_modules/tar": { + "version": "6.2.0", +======= + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=0.10" + "node": ">=6" } }, "node_modules/tar": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -18458,8 +25665,9 @@ }, "node_modules/tar/node_modules/fs-minipass": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -18469,8 +25677,9 @@ }, "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -18480,16 +25689,32 @@ }, "node_modules/tar/node_modules/minipass": { "version": "5.0.0", +<<<<<<< HEAD "dev": true, "license": "ISC", +======= + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=8" } }, +<<<<<<< HEAD +======= + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/terser": { "version": "5.16.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", + "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", @@ -18503,11 +25728,18 @@ "node": ">=10" } }, +<<<<<<< HEAD "node_modules/terser/node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", +======= + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" @@ -18518,29 +25750,180 @@ }, "node_modules/terser/node_modules/@jridgewell/source-map": { "version": "0.3.5", +======= + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { +<<<<<<< HEAD "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" +======= + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/terser": { + "version": "5.26.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz", + "integrity": "sha512-dytTGoE2oHgbNV9nTzgBEPaqAWvcJNl66VZ0BkJqlvp71IjO8CxdBx/ykCNb47cLnCmCvRZ6ZR0tLkqvZCdVBQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "license": "MIT" + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/text-table": { "version": "0.2.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, +<<<<<<< HEAD +======= + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/thunky": { "version": "1.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true }, "node_modules/tmp": { +<<<<<<< HEAD "version": "0.0.30", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", "integrity": "sha512-HXdTB7lvMwcb55XFfrTM8CPr/IYREk4hVBFaQ4b/6nInrluSL86hfHm7vu0luYKCfyBZp2trCjpc8caC3vVM3w==", @@ -18550,6 +25933,17 @@ }, "engines": { "node": ">=0.4.0" +======= + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) } }, "node_modules/to-fast-properties": { @@ -18561,6 +25955,30 @@ "node": ">=4" } }, +<<<<<<< HEAD +======= + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "devOptional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -18576,16 +25994,22 @@ }, "node_modules/tree-kill": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true, - "license": "MIT", "bin": { "tree-kill": "cli.js" } }, "node_modules/ts-api-utils": { +<<<<<<< HEAD "version": "1.0.2", +======= + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "engines": { "node": ">=16.13.0" }, @@ -18595,8 +26019,9 @@ }, "node_modules/ts-node": { "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, - "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -18636,9 +26061,14 @@ } }, "node_modules/tsconfig-paths": { +<<<<<<< HEAD "version": "3.14.2", +======= + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -18646,6 +26076,7 @@ "strip-bom": "^3.0.0" } }, +<<<<<<< HEAD "node_modules/tsconfig-paths/node_modules/minimist": { "version": "1.2.8", "dev": true, @@ -18654,18 +26085,142 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "license": "0BSD" + }, +======= + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tuf-js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-1.1.7.tgz", + "integrity": "sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==", + "dev": true, + "dependencies": { + "@tufjs/models": "1.0.4", + "debug": "^4.3.4", + "make-fetch-happen": "^11.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/tuf-js/node_modules/make-fetch-happen": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz", + "integrity": "sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=4" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/tslib": { - "version": "2.6.2", - "license": "0BSD" - }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -18683,11 +26238,27 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true +<<<<<<< HEAD +======= + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/type-fest": { "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -18695,10 +26266,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, +<<<<<<< HEAD "node_modules/typed-array-buffer": { "version": "1.0.0", +======= + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -18920,10 +26497,62 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -18933,6 +26562,7 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD "node_modules/typed-array-length/node_modules/call-bind": { "version": "1.0.5", "dev": true, @@ -18991,11 +26621,19 @@ "funding": { "url": "https://github.com/sponsors/ljharb" } +======= + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/typescript": { "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -19004,10 +26642,37 @@ "node": ">=4.2.0" } }, +<<<<<<< HEAD +======= + "node_modules/ua-parser-js": { + "version": "0.7.37", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz", + "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "engines": { + "node": "*" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/unbox-primitive": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -19130,16 +26795,18 @@ }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, - "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -19150,24 +26817,27 @@ }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unique-filename": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -19177,8 +26847,9 @@ }, "node_modules/unique-slug": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -19186,8 +26857,31 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/update-browserslist-db": { - "version": "1.0.11", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -19203,7 +26897,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -19228,22 +26921,42 @@ "punycode": "^2.1.0" } }, +<<<<<<< HEAD +======= + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/uuid": { "version": "9.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true }, "node_modules/validate-npm-package-license": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -19251,8 +26964,9 @@ }, "node_modules/validate-npm-package-name": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", "dev": true, - "license": "ISC", "dependencies": { "builtins": "^5.0.0" }, @@ -19260,6 +26974,18 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -19274,10 +27000,29 @@ "extsprintf": "^1.2.0" } }, +<<<<<<< HEAD +======= + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/watchpack": { "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, - "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -19293,12 +27038,24 @@ }, "node_modules/wbuf": { "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, - "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } }, +<<<<<<< HEAD +======= + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/webdriver-js-extender": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz", @@ -19312,6 +27069,7 @@ "node": ">=6.9.x" } }, +<<<<<<< HEAD "node_modules/webdriver-manager": { "version": "12.1.9", "dev": true, @@ -19438,10 +27196,13 @@ "node": ">=0.8.0" } }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/webpack": { "version": "5.76.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz", + "integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -19486,8 +27247,9 @@ }, "node_modules/webpack-dev-middleware": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.0.1.tgz", + "integrity": "sha512-PZPZ6jFinmqVPJZbisfggDiC+2EeGZ1ZByyMP5sOFJcPPWSexalISz+cvm+j+oYPT7FIJyxT76esjnw9DhE5sw==", "dev": true, - "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.12", @@ -19560,8 +27322,9 @@ }, "node_modules/webpack-dev-server": { "version": "4.11.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", + "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", "dev": true, - "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -19734,8 +27497,9 @@ }, "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "dev": true, - "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -19776,8 +27540,9 @@ }, "node_modules/webpack-merge": { "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", "dev": true, - "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "wildcard": "^2.0.0" @@ -19786,15 +27551,27 @@ "node": ">=10.0.0" } }, +<<<<<<< HEAD "node_modules/webpack-merge/node_modules/wildcard": { "version": "2.0.1", "dev": true, "license": "MIT" +======= + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/webpack-subresource-integrity": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", "dev": true, - "license": "MIT", "dependencies": { "typed-assert": "^1.0.8" }, @@ -19862,8 +27639,9 @@ }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -19877,16 +27655,25 @@ }, "node_modules/webpack/node_modules/ajv-keywords": { "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, +<<<<<<< HEAD "node_modules/webpack/node_modules/commander": { "version": "2.20.3", "dev": true, "license": "MIT" +======= + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) }, "node_modules/webpack/node_modules/enhanced-resolve": { "version": "5.15.0", @@ -19959,8 +27746,12 @@ }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", +<<<<<<< HEAD +======= + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -20064,8 +27855,9 @@ }, "node_modules/websocket-driver": { "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -20077,16 +27869,52 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } }, +<<<<<<< HEAD +======= + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/which-collection": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "dev": true, - "license": "MIT", "dependencies": { "is-map": "^2.0.1", "is-set": "^2.0.1", @@ -20097,14 +27925,44 @@ "url": "https://github.com/sponsors/ljharb" } }, +<<<<<<< HEAD +======= + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/wide-align": { "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, +<<<<<<< HEAD "node_modules/wide-align/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "dev": true, @@ -20115,8 +27973,19 @@ }, "node_modules/wide-align/node_modules/string-width": { "version": "4.2.3", +======= + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -20137,6 +28006,7 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", @@ -20189,8 +28059,13 @@ }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", +======= + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -20200,10 +28075,16 @@ "node": ">=8" } }, +<<<<<<< HEAD "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", +======= + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dev": true, - "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -20211,16 +28092,26 @@ "node": ">=8" } }, +<<<<<<< HEAD +======= + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "node_modules/ws": { - "version": "8.11.0", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -20253,23 +28144,38 @@ "node": ">=4.0" } }, - "node_modules/yallist": { - "version": "4.0.0", +<<<<<<< HEAD +======= + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "license": "ISC" + "engines": { + "node": ">=10" + } + }, +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/yaml": { "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, - "license": "ISC", "engines": { "node": ">= 6" } }, "node_modules/yargs": { "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -20285,7 +28191,10 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, +<<<<<<< HEAD "license": "ISC", "engines": { "node": ">=12" @@ -20314,6 +28223,8 @@ "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" }, +======= +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "engines": { "node": ">=12" } @@ -20403,15 +28314,35 @@ }, "node_modules/yn": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, +<<<<<<< HEAD "node_modules/zone.js": { "version": "0.13.1", "license": "MIT", +======= + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.0.tgz", + "integrity": "sha512-7m3hNNyswsdoDobCkYNAy5WiUulkMd3+fWaGT9ij6iq3Zr/IwJo4RMCYPSDjT+r7tnPErmY9sZpKhWQ8S5k6XQ==", +>>>>>>> 3fb12e3030 (UI: Backport of chartjs-migration (#990)) "dependencies": { "tslib": "^2.3.0" } diff --git a/ui/package.json b/ui/package.json index 9f342d2b4bb..211d47c6112 100644 --- a/ui/package.json +++ b/ui/package.json @@ -5,6 +5,7 @@ "private": true, "dependencies": { "@angular/animations": "~15.2.9", + "@angular/cdk": "~15.2.9", "@angular/common": "~15.2.9", "@angular/core": "~15.2.9", "@angular/forms": "~15.2.9", @@ -18,13 +19,15 @@ "@ngx-formly/schematics": "^6.1.7", "@ngx-translate/core": "^14.0.0", "angular-mydatepicker": "^0.11.5", - "chart.js": "^2.9.4", + "chart.js": "^4.4.0", + "chartjs-adapter-date-fns": "^3.0.0", + "chartjs-plugin-zoom": "^2.0.1", "classlist.js": "^1.1.20150312", "compare-versions": "^6.1.0", "d3": "^7.8.5", "date-fns": "^2.30.0", "file-saver-es": "^2.0.5", - "ng2-charts": "^2.4.3", + "ng2-charts": "4.1.1", "ngx-cookie-service": "^15.0.0", "ngx-spinner": "^15.0.1", "roboto-fontface": "^0.10.0", @@ -71,4 +74,4 @@ "lint": "ng lint", "test": "ng test" } -} \ No newline at end of file +} diff --git a/ui/src/app/edge/history/Controller/ChannelThreshold/chart/totalchart.component.ts b/ui/src/app/edge/history/Controller/ChannelThreshold/chart/totalchart.component.ts index 4645707dd70..0fec3b41f12 100644 --- a/ui/src/app/edge/history/Controller/ChannelThreshold/chart/totalchart.component.ts +++ b/ui/src/app/edge/history/Controller/ChannelThreshold/chart/totalchart.component.ts @@ -51,6 +51,7 @@ export class TotalChartComponent extends AbstractHistoryChart { .map(val => Utils.multiplySafely(val, 1000)); }, color: colors[Math.min(i % colors.length, (colors.length - 1))], + stack: 0, }); } diff --git a/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/chart/chart.ts b/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/chart/chart.ts index 874ef4e3ae3..99e8ca19e08 100644 --- a/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/chart/chart.ts +++ b/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/chart/chart.ts @@ -1,8 +1,10 @@ import { Component, Input } from '@angular/core'; -import { ChronoUnit, Data, Resolution, TooltipItem, calculateResolution } from 'src/app/edge/history/shared'; -import { AbstractHistoryChart, ChartType } from 'src/app/shared/genericComponents/chart/abstracthistorychart'; +import * as Chart from 'chart.js'; +import { calculateResolution, ChronoUnit, Resolution } from 'src/app/edge/history/shared'; +import { AbstractHistoryChart } from 'src/app/shared/genericComponents/chart/abstracthistorychart'; import { ChartAxis, HistoryUtils, TimeOfUseTariffUtils, Utils, YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Currency, EdgeConfig } from "src/app/shared/shared"; +import { ColorUtils } from 'src/app/shared/utils/color/color.utils'; @Component({ selector: 'scheduleChart', @@ -16,17 +18,13 @@ export class ChartComponent extends AbstractHistoryChart { private currencyLabel: Currency.Label; // Default protected override getChartData(): HistoryUtils.ChartData { - const components: EdgeConfig.Component[] = this.config.getComponentsByFactory('Controller.Ess.Time-Of-Use-Tariff'); - - // Assiging the component to be able to use the id. - // There will always be only one controller enabled for Time-of-Use-Tariff. So finding the controller which is enabled. - this.component = components.length > 1 - ? components.find(component => component.isEnabled) - : components[0]; + // Assigning the component to be able to use the id. + const componentId: string = this.config.getComponentIdsByFactory('Controller.Ess.Time-Of-Use-Tariff')[0]; + this.component = this.config.components[componentId]; const currency = this.config.components['_meta'].properties.currency; this.currencyLabel = Currency.getCurrencyLabelByCurrency(currency); - this.chartType = ChartType.BAR; + this.chartType = 'bar'; return { input: [ @@ -76,15 +74,20 @@ export class ChartComponent extends AbstractHistoryChart { color: 'rgb(189, 195, 199)', borderDash: [10, 10], yAxisId: ChartAxis.RIGHT, - customType: ChartType.LINE, - customUnit: YAxisTitle.PERCENTAGE, - }]; + custom: { + type: 'line', + unit: YAxisTitle.PERCENTAGE, + formatNumber: '1.0-0', + }, + order: 0, + }, + ]; }, tooltip: { - formatNumber: '1.1-2', + formatNumber: '1.1-4', }, yAxes: [{ - unit: YAxisTitle.ENERGY, + unit: YAxisTitle.CURRENCY, position: 'left', yAxisId: ChartAxis.LEFT, }, @@ -93,7 +96,8 @@ export class ChartComponent extends AbstractHistoryChart { position: 'right', yAxisId: ChartAxis.RIGHT, displayGrid: false, - }], + }, + ], }; } @@ -102,31 +106,52 @@ export class ChartComponent extends AbstractHistoryChart { this.errorResponse = null; const unit: Resolution = { unit: ChronoUnit.Type.MINUTES, value: 15 }; + let displayValues; this.queryHistoricTimeseriesData(this.service.historyPeriod.value.from, this.service.historyPeriod.value.to, unit) .then((dataResponse) => { - const displayValues = AbstractHistoryChart.fillChart(this.chartType, this.chartObject, dataResponse); + this.chartType = 'line'; + this.chartObject = this.getChartData(); + + displayValues = AbstractHistoryChart.fillChart(this.chartType, this.chartObject, dataResponse); this.datasets = displayValues.datasets; - this.colors = displayValues.colors; this.legendOptions = displayValues.legendOptions; this.labels = displayValues.labels; this.setChartLabel(); - }).finally(() => { - this.options.scales.xAxes[0].time.unit = calculateResolution(this.service, this.service.historyPeriod.value.from, this.service.historyPeriod.value.to).timeFormat; - this.options.scales.xAxes[0].ticks.source = 'auto'; - this.options.tooltips.mode = 'index'; - this.options.scales.xAxes[0].ticks.maxTicksLimit = 31; - this.options.scales.yAxes[0].ticks.min = this.getMinimumAxisValue(this.datasets); - this.options.scales.xAxes[0].offset = false; - - this.options.tooltips.callbacks.label = (tooltipItem: TooltipItem, data: Data) => { - const label: string = data.datasets[tooltipItem.datasetIndex].label; - const value: number = tooltipItem.value; + + let values = this.chartObject.output(dataResponse.result.data); + this.options.scales.x['time'].unit = calculateResolution(this.service, this.service.historyPeriod.value.from, this.service.historyPeriod.value.to).timeFormat; + this.options.scales.x.ticks['source'] = 'auto'; + this.options.scales.x.grid = { offset: false }; + this.options.plugins.tooltip.mode = 'index'; + this.options.scales.x.ticks.maxTicksLimit = 30; + this.options.scales[ChartAxis.LEFT].min = this.getMinimumAxisValue(this.datasets); + + this.options.plugins.tooltip.callbacks.labelColor = (item: Chart.TooltipItem) => { + return { + borderColor: ColorUtils.changeOpacityFromRGBA(item.dataset.borderColor, 1), + backgroundColor: item.dataset.backgroundColor, + }; + }; + this.options.scales.x['bounds'] = 'ticks'; + + this.options.plugins.tooltip.callbacks.label = (item: Chart.TooltipItem) => { + const label = item.dataset.label; + const value = item.dataset.data[item.dataIndex]; return TimeOfUseTariffUtils.getLabel(value, label, this.translate, this.currencyLabel); }; - this.options.scales.yAxes[0].scaleLabel.labelString = this.currencyLabel; + this.options.scales[ChartAxis.LEFT]['title'].text = this.currencyLabel; + this.datasets = this.datasets.map((el) => { + let opacity = el.type === 'line' ? 0.2 : 0.5; + + el.backgroundColor = ColorUtils.changeOpacityFromRGBA(el.backgroundColor.toString(), opacity); + el.borderColor = ColorUtils.changeOpacityFromRGBA(el.borderColor.toString(), 1); + return el; + }); + + this.options.scales.x['offset'] = false; }); } @@ -163,7 +188,7 @@ export class ChartComponent extends AbstractHistoryChart { * @param datasets The chart datasets. * @returns the minumum axis value. */ - private getMinimumAxisValue(datasets: Chart.ChartDataSets[]): number { + private getMinimumAxisValue(datasets: Chart.ChartDataset[]): number { const labels = [ this.translate.instant('Edge.Index.Widgets.TIME_OF_USE_TARIFF.STATE.BALANCING'), diff --git a/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.html b/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.html index 4c68954d4ef..96ad055397c 100644 --- a/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.html +++ b/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.html @@ -5,6 +5,6 @@ [value]="delayedActiveTimeOverPeriod | formatSecondsToDuration"> + [value]="chargedConsumptionActiveTimeOverPeriod | formatSecondsToDuration"> diff --git a/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.ts b/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.ts index 4734c5e3adc..ea86a49ea0b 100644 --- a/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.ts +++ b/ui/src/app/edge/history/Controller/Ess/TimeOfUseTariff/flat/flat.ts @@ -13,7 +13,6 @@ export class FlatComponent extends AbstractFlatWidget { @Input() public period: DefaultTypes.HistoryPeriod; protected delayedActiveTimeOverPeriod: number | null = null; - protected chargedProductionActiveTimeOverPeriod: number | null = null; protected chargedConsumptionActiveTimeOverPeriod: number | null = null; protected override onCurrentData(currentData: CurrentData) { diff --git a/ui/src/app/edge/history/abstracthistorychart.html b/ui/src/app/edge/history/abstracthistorychart.html index 5c6153c4e43..086f2be9aff 100644 --- a/ui/src/app/edge/history/abstracthistorychart.html +++ b/ui/src/app/edge/history/abstracthistorychart.html @@ -3,7 +3,6 @@

- +
\ No newline at end of file diff --git a/ui/src/app/edge/history/abstracthistorychart.ts b/ui/src/app/edge/history/abstracthistorychart.ts index 8f35391e8d8..8a5a35447dc 100644 --- a/ui/src/app/edge/history/abstracthistorychart.ts +++ b/ui/src/app/edge/history/abstracthistorychart.ts @@ -1,18 +1,18 @@ -import { Data } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { ChartDataSets } from 'chart.js'; -import { differenceInDays, differenceInMonths } from 'date-fns'; +import * as Chart from 'chart.js'; +import { AbstractHistoryChart as NewAbstractHistoryChart } from 'src/app/shared/genericComponents/chart/abstracthistorychart'; import { JsonrpcResponseError } from 'src/app/shared/jsonrpc/base'; import { QueryHistoricTimeseriesDataRequest } from "src/app/shared/jsonrpc/request/queryHistoricTimeseriesDataRequest"; import { QueryHistoricTimeseriesEnergyPerPeriodRequest } from 'src/app/shared/jsonrpc/request/queryHistoricTimeseriesEnergyPerPeriodRequest'; import { QueryHistoricTimeseriesDataResponse } from "src/app/shared/jsonrpc/response/queryHistoricTimeseriesDataResponse"; import { QueryHistoricTimeseriesEnergyPerPeriodResponse } from 'src/app/shared/jsonrpc/response/queryHistoricTimeseriesEnergyPerPeriodResponse'; -import { HistoryUtils } from 'src/app/shared/service/utils'; +import { ChartAxis, HistoryUtils, YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from "src/app/shared/shared"; import { DateUtils } from 'src/app/shared/utils/date/dateutils'; import { DateTimeUtils } from 'src/app/shared/utils/datetime/datetime-utils'; -import { calculateResolution, ChartOptions, DEFAULT_TIME_CHART_OPTIONS, EMPTY_DATASET, Resolution, TooltipItem } from './shared'; +import { calculateResolution, DEFAULT_TIME_CHART_OPTIONS, EMPTY_DATASET, Resolution } from './shared'; +import { ChronoUnit, setLabelVisible } from './shared'; // NOTE: Auto-refresh of widgets is currently disabled to reduce server load export abstract class AbstractHistoryChart { @@ -30,12 +30,17 @@ export abstract class AbstractHistoryChart { // private ngUnsubscribe: Subject = new Subject(); public labels: Date[] = []; - public datasets: ChartDataSets[] = HistoryUtils.createEmptyDataset(this.translate); - public options: ChartOptions | null = DEFAULT_TIME_CHART_OPTIONS; + public datasets: Chart.ChartDataset[] = []; + public options: Chart.ChartOptions | null = null; public colors = []; // prevents subscribing more than once protected hasSubscribed: boolean = false; + /** @deprecated*/ + protected unit: YAxisTitle = YAxisTitle.ENERGY; + /** @deprecated*/ + protected formatNumber: string = '1.0-2'; + // Colors for Phase 1-3 protected phase1Color = { backgroundColor: 'rgba(255,127,80,0.05)', @@ -159,12 +164,16 @@ export abstract class AbstractHistoryChart { * @param date Date from TooltipItem * @returns period for Tooltip Header */ - protected toTooltipTitle(fromDate: Date, toDate: Date, date: Date): string { - if (this.service.periodString == 'year') { + protected static toTooltipTitle(fromDate: Date, toDate: Date, date: Date, service: Service): string { + let unit = calculateResolution(service, fromDate, toDate).resolution.unit; + if (unit == ChronoUnit.Type.MONTHS) { return date.toLocaleDateString('default', { month: 'long' }); - } else if (this.service.periodString == 'month') { + + } else if (unit == ChronoUnit.Type.DAYS) { return date.toLocaleDateString('default', { day: '2-digit', month: 'long' }); + } else { + // Default return date.toLocaleString('default', { day: '2-digit', month: '2-digit', year: '2-digit' }) + ' ' + date.toLocaleTimeString('default', { hour12: false, hour: '2-digit', minute: '2-digit' }); } } @@ -176,23 +185,8 @@ export abstract class AbstractHistoryChart { * * @returns the ChartOptions */ - protected createDefaultChartOptions(): ChartOptions { - let options = Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS); - - // Overwrite TooltipsTitle - options.tooltips.callbacks.title = (tooltipItems: TooltipItem[], data: Data): string => { - let date = new Date(tooltipItems[0].xLabel); - return this.toTooltipTitle(this.service.historyPeriod.value.from, this.service.historyPeriod.value.to, date); - }; - - //x-axis - if (differenceInMonths(this.service.historyPeriod.value.to, this.service.historyPeriod.value.from) > 1) { - options.scales.xAxes[0].time.unit = "month"; - } else if (differenceInDays(this.service.historyPeriod.value.to, this.service.historyPeriod.value.from) >= 5 && differenceInMonths(this.service.historyPeriod.value.to, this.service.historyPeriod.value.from) <= 1) { - options.scales.xAxes[0].time.unit = "day"; - } else { - options.scales.xAxes[0].time.unit = "hour"; - } + protected createDefaultChartOptions(): Chart.ChartOptions { + let options = Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS); return options; } @@ -293,4 +287,148 @@ export abstract class AbstractHistoryChart { this.service.stopSpinner(this.spinnerId); } + /** + * + * Sets chart options + * + * @deprecated used for charts not using {@link NewAbstractHistoryChart} but {@link AbstractHistoryChart} + */ + public setOptions(options: Chart.ChartOptions): Promise { + + return new Promise((resolve) => { + const locale = this.service.translate.currentLang; + const yAxis: HistoryUtils.yAxes = { position: 'left', unit: this.unit, yAxisId: ChartAxis.LEFT }; + const chartObject: HistoryUtils.ChartData = { + input: [], + output: () => [], + yAxes: [yAxis], + tooltip: { + formatNumber: this.formatNumber, + }, + }; + const unit = this.unit; + const formatNumber = this.formatNumber; + const colors = this.colors; + const translate = this.translate; + this.service.getConfig().then((conf) => { + options.datasets.line.borderWidth = 2; + + /** Hide default displayed yAxis */ + options.scales['y'] = { + display: false, + }; + + // Overwrite TooltipsTitle + options.plugins.tooltip.callbacks.title = (tooltipItems: Chart.TooltipItem[]): string => { + if (tooltipItems?.length === 0) { + return null; + } + let date = DateUtils.stringToDate(tooltipItems[0]?.label); + return AbstractHistoryChart.toTooltipTitle(this.service.historyPeriod.value.from, this.service.historyPeriod.value.to, date, this.service); + }; + + options.plugins.tooltip.callbacks.label = function (tooltipItem: Chart.TooltipItem) { + let label = tooltipItem.dataset.label; + let value = tooltipItem.dataset.data[tooltipItem.dataIndex]; + + const customUnit = tooltipItem.dataset.unit ?? null; + return label.split(":")[0] + ": " + NewAbstractHistoryChart.getToolTipsSuffix("", value, formatNumber, customUnit ?? unit, 'line', locale, translate, conf); + }; + + options.plugins.tooltip.callbacks.labelColor = (item: Chart.TooltipItem) => { + const color = colors[item.datasetIndex]; + + if (!color) { + return; + } + + return { + borderColor: color.borderColor, + backgroundColor: color.backgroundColor, + }; + }; + + options.plugins.legend.labels.generateLabels = function (chart: Chart.Chart) { + let chartLegendLabelItems: Chart.LegendItem[] = []; + chart.data.datasets.forEach((dataset, index) => { + + const color = colors[index]; + + if (!color) { + return; + } + + // Set colors manually + dataset.backgroundColor = color.backgroundColor ?? dataset.backgroundColor; + dataset.borderColor = color.borderColor ?? dataset.borderColor; + + chartLegendLabelItems.push({ + text: dataset.label, + datasetIndex: index, + fillStyle: color.backgroundColor, + fontColor: getComputedStyle(document.documentElement).getPropertyValue('--ion-color-text'), + hidden: !chart.isDatasetVisible(index), + lineWidth: 2, + ...(dataset['borderDash'] && { lineDash: dataset['borderDash'] }), + strokeStyle: color.borderColor, + }); + }); + return chartLegendLabelItems; + }; + + // Remove duplicates from legend, if legendItem with two or more occurrences in legend, use one legendItem to trigger them both + options.plugins.legend.onClick = function (event: Chart.ChartEvent, legendItem: Chart.LegendItem, legend) { + let chart: Chart.Chart = this.chart; + + let legendItems = chart.data.datasets.reduce((arr, ds, i) => { + if (ds.label == legendItem.text) { + arr.push({ label: ds.label, index: i }); + } + return arr; + }, []); + + legendItems.forEach(item => { + // original.call(this, event, legendItem1); + setLabelVisible(item.label, !chart.isDatasetVisible(legendItem.datasetIndex)); + var meta = chart.getDatasetMeta(item.index); + // See controller.isDatasetVisible comment + meta.hidden = meta.hidden === null ? !chart.data.datasets[item.index].hidden : null; + }); + + // We hid a dataset ... rerender the chart + chart.update(); + }; + + options = NewAbstractHistoryChart.getYAxisOptions(options, yAxis, this.translate, 'line', locale); + + const timeFormat = calculateResolution(this.service, this.service.historyPeriod.value.from, this.service.historyPeriod.value.to).timeFormat; + options.scales.x['time'].unit = timeFormat; + switch (timeFormat) { + case 'hour': + options.scales.x.ticks['source'] = 'auto';//labels,auto + options.scales.x.ticks.maxTicksLimit = 31; + break; + case 'day': + case 'month': + options.scales.x.ticks['source'] = 'data'; + break; + } + + options.scales.x['stacked'] = true; + options.scales[ChartAxis.LEFT]['stacked'] = false; + + NewAbstractHistoryChart.applyChartTypeSpecificOptionsChanges('line', options, this.service, chartObject); + + /** Overwrite default yAxisId */ + this.datasets = this.datasets + .map(el => { + el['yAxisID'] = ChartAxis.LEFT; + return el; + }); + }).then(() => { + this.options = options; + resolve(); + }); + }); + } } diff --git a/ui/src/app/edge/history/chpsoc/chart.component.ts b/ui/src/app/edge/history/chpsoc/chart.component.ts index 22f6e325c95..b82dd0114de 100644 --- a/ui/src/app/edge/history/chpsoc/chart.component.ts +++ b/ui/src/app/edge/history/chpsoc/chart.component.ts @@ -1,4 +1,3 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -6,7 +5,7 @@ import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from './../shared'; +import { YAxisTitle } from 'src/app/shared/service/utils'; @Component({ selector: 'chpsocchart', @@ -29,7 +28,6 @@ export class ChpSocChartComponent extends AbstractHistoryChart implements OnInit super("chpsoc-chart", service, translate); } - ngOnInit() { this.startSpinner(); this.service.setCurrentComponent('', this.route); @@ -141,7 +139,10 @@ export class ChpSocChartComponent extends AbstractHistoryChart implements OnInit console.error(reason); // TODO error message this.initializeChart(); return; - }); + }).finally(() => { + this.unit = YAxisTitle.PERCENTAGE; + this.setOptions(this.options); + });; } protected getChannelAddresses(edge: Edge, config: EdgeConfig): Promise { @@ -159,15 +160,7 @@ export class ChpSocChartComponent extends AbstractHistoryChart implements OnInit } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = this.translate.instant('General.percentage'); - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; // TODO get locale dynamically - }; - options.scales.yAxes[0].ticks.max = 100; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/common/consumption/chart/chart.constants.spec.ts b/ui/src/app/edge/history/common/consumption/chart/chart.constants.spec.ts index 39e619fa3e4..014c7aff208 100644 --- a/ui/src/app/edge/history/common/consumption/chart/chart.constants.spec.ts +++ b/ui/src/app/edge/history/common/consumption/chart/chart.constants.spec.ts @@ -1,10 +1,10 @@ import { DummyConfig } from "src/app/shared/edge/edgeconfig.spec"; +import { OeTester } from "src/app/shared/genericComponents/shared/testing/common"; +import { OeChartTester } from "src/app/shared/genericComponents/shared/testing/tester"; import { EdgeConfig } from "src/app/shared/shared"; import { removeFunctions, TestContext } from "src/app/shared/test/utils.spec"; import { ChartComponent } from "./chart"; -import { OeTester } from "src/app/shared/genericComponents/shared/testing/common"; -import { OeChartTester } from "src/app/shared/genericComponents/shared/testing/tester"; export function expectView(config: EdgeConfig, testContext: TestContext, chartType: 'line' | 'bar', channels: OeTester.Types.Channels, view: OeChartTester.View): void { @@ -12,6 +12,6 @@ export function expectView(config: EdgeConfig, testContext: TestContext, chartTy .apply(ChartComponent .getChartData( DummyConfig.convertDummyEdgeConfigToRealEdgeConfig(config), - testContext.translate), chartType, channels, testContext))) + testContext.translate), chartType, channels, testContext, config))) .toEqual(removeFunctions(view)); }; diff --git a/ui/src/app/edge/history/common/consumption/chart/chart.spec.ts b/ui/src/app/edge/history/common/consumption/chart/chart.spec.ts index 68d01e1c094..1030258130b 100644 --- a/ui/src/app/edge/history/common/consumption/chart/chart.spec.ts +++ b/ui/src/app/edge/history/common/consumption/chart/chart.spec.ts @@ -30,7 +30,7 @@ describe('History Consumption', () => { DATA('Sonstiger: 63,3 kWh', [null, null, null, 0.5658045977011494, 0.3871815181518151, 0.561425925925926, 0.5732169811320755, 0.5658080808080809, 0.5879803921568627, 0.5842389380530973, 0.6074818181818182, 0.6050275229357799, 0.5956407766990292, 0.6025294117647059, 0.5781684210526317, 0.5816813186813187, 0.6495166666666666, 0.5602999999999999, 0.56703738317757, 0.6297672413793104, 0.5688613861386138, 0.5896039603960396, 0.5245090909090909, 0.5093300330033004, 0.6177196261682243, 0.608122641509434, 0.60278, 0.6508155339805825, 0.6058877551020408, 0.5943904761904762, 0.57636, 0.5650660377358491, 0.587495145631068, 0.626375, 0.6819428571428572, 0.6504629629629629, 0.6313738317757009, 0.68725, 0.5602452830188679, 0.5278952380952382, 0.6202222222222221, 0.4016355140186916, 0.5878130841121496, 0.604, 0.616295918367347, 0.5789405940594059, 0.5943396226415094, 0.6481078431372549, null, null, null, 0.5652183908045977, 0.5736481481481481, 0.5365462962962964, 0.558081081081081, 0.5747543859649124, 0.5743557692307693, 0.5969047619047619, 0.6540720720720721, 0.5018766666666667, 0.6128045977011494, 0.6361100000000001, 0.6137948717948718, 0.5388857142857142, 0.5371157894736842, 0.5511634615384615, 0.5588809523809524, 0.5591222222222223, 0.6185576923076923, 0.6543287671232877, 0.6160574712643678, 0.5889056603773585, 0.5787096774193549, 0.583036036036036, 0.572570093457944, 0.5952631578947368, 0.7450888888888888, 0.7073990610328639, -1.452950549450549, 2.233161450571287, 1.1458434343434352, 1.2180771929824568, 0.9178416666666669, 0.9020510752688171, 1.3458171717171723, 1.1460410714285718, 0.9853455165691996, 1.189936077481839, -1.4153224202237875, 0.6774427860696518, 0.9827305699481865, 0.8582012987012987, 0.7678924050632912, 0.761950495049505, 0.6821319796954315, 0.5954198473282443, 0.7021286549707602, 0.7309484536082475, 0.739, 0.730572864321608, 0.7547467532467532, 0.657373417721519, 0.6409480519480519, 0.6698156424581005, 0.7876280991735537, 2.931229357798165, 1.9542808988764044, 0.7775346534653466, 1.098538860103627, 1.2441524390243903, 2.9194913793103447, 2.9874188034188034, 3.4140294117647056, 1.2151999999999998, 2.7142824427480914, 2.6578703703703703, 2.8738923076923077, 4.013462078651685, 3.791560606060606, 2.845578947368421, 1.7741875, 0.89646, 1.2468691588785048, 1.0760386740331491, 0.8393491124260355, 1.194960199004975, 1.0562878787878787, 3.133, 3.78845625, 1.288096153846154, 3.4541666666666666, 2.0936967871485943, 2.384391025641026, 1.6707888888888887, 1.5589767441860465, 2.8620799999999997, 2.3241241379310345, 1.9640169491525423, 1.8084, 3.4660503597122303, 2.2974397590361444, 2.5300493827160495, 2.439358490566038, 2.0079060773480664, 1.7515, 1.4163181818181818, 1.4292298850574712, 1.4520298507462688, 1.4897204301075269, 1.6330952380952382, 1.8262928571428572, 1.6101904761904762, 1.680929292929293, 2.881743119266055, 3.5851634615384613, 3.6891666666666665, 3.6573402777777777, 3.6435348837209305, 3.7148645833333336, 3.731375, 3.74479, 3.6362363636363635, 4.273113924050633, 3.4461999999999997, 3.5387142857142857, 3.7906065573770493, 3.5276750000000003, 3.4676712328767123, 3.5595, 3.7982, 5.460666666666667, 1.3094406779661016, 1.5357454545454545, 3.4238260869565216, 3.3823636363636367, 3.4006315789473684, 2.95075, 3.386731707317073, 2.506, 1.4471666666666667, 1.4425999999999999, 0.946, 0.9425789473684211, 0.9507142857142856, 0.947, 0.9762857142857143, 1.7862857142857143, 1.5135777777777777, 1.4995625, 1.338, 1.3278125, 1.2739175257731958, 1.4387457627118645, 1.2484186046511627, 1.2866693548387098, 1.2848934911242604, 1.2237952755905512, 0.74809375, 0.8717684210526315, 0.8445338983050847, 0.7916749999999999, 0.8041932773109244, 0.7303737373737375, 0.7055024390243902, 0.6872407407407407, 0.6909939759036144, 0.751, 0.765139344262295, 0.686871794871795, 0.6697434210526315, 1.7678091603053436, 0.7246764705882353, 0.7482772277227723, 0.9401142857142858, 0.750368, 1.3660232558139536, 0.7274137931034482, 0.710719512195122, 0.6898555555555557, 0.739453488372093, 0.817875, 0.7304303797468354, 0.7355890410958904, 0.738225806451613, 1.906921739130435, 2.290785714285714, 1.2075072463768115, 1.1675890410958905, 1.2290208333333332, 1.1923777777777778, 1.2088717948717949, 1.367715909090909, 1.284223300970874, 1.1631739130434782, 1.15253, 1.1614545454545455, 1.2195681818181818, 1.183752808988764, 1.197778947368421, 1.2338888888888888, 1.275070588235294, 1.235554054054054, 1.20783908045977, 1.2416184210526318, 1.159042735042735, 1.1382948717948718, 1.1069915966386554, 1.1714504504504506, 1.223822429906542, 1.1221696428571428, 1.018892857142857, 0.9818285714285714, 0.9988363636363636, 0.8434776785714284, 1.4379482009925546, 1.4043499341238475, 1.7165029190992493, 1.781351488095238, 1.8585528255528247, 3.6707709585574175, 4.427144379844961, 4.301046195652174, 4.194778846153845, 4.150229357798166, 4.055816642120766, 3.976974967061925, 2.711485714285714, 1.0600519480519486, 0.954382608695652, 0.7914855072463762, 0.9272300420168067, 0.28519157088122604, 0.8123142857142857, 0.8095892857142857, 0.8664786324786324, 0.8778319327731092, 0.8108141592920354, 0.8157121212121212, 0.7706470588235294, 0.7633157894736842, 0.7815151515151515, 0.8075833333333333, 0.824743119266055, 0.8762151898734176, 0.882424, 0.7502213114754098, 0.675954954954955, 0.6371222222222223]), ], labels: LABELS(History.DAY.dataChannelWithValues.result.timestamps), - options: ChartConfig.LINE_CHART_OPTIONS('hour'), + options: ChartConfig.LINE_CHART_OPTIONS('hour', 'line'), }, }); } @@ -47,7 +47,7 @@ describe('History Consumption', () => { DATA('Sonstiger: 97,1 kWh', [0.6360308446701046, 0.9095864441102458, 0.7335808811402847, 0.5718131699718612, 0.9616446485934361, 0.6381720132750589, 1.02619037791046, 1.0145027809280902, 0.6390464755453447, 0.7096512022948386, 0.819995628581571, 0.935642813016216, 0.5254472085206601, 1.8851739940941776, 0.863444783197832, 1.1921009009810684, 0.5202376219567795, 0.7444045122530605, 0.901856453684574, 0.8104459244359407, 1.0830737950562592, 0.8714288985355628, 0.7780086316183336, 0.9590122781645534, 0.58627825521263, 0.8413148987905428, 0.8796668002158831, 0.6461976914860288, 0.8006733468796897, 0.8250297170962498, 0.825867009418173, 0.8407590098644301, 1.2782520162083928, 0.9299547986301717, 1.100431849409396, 0.881695115377627, -3.0801277220264014, 0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]), ], labels: LABELS(History.WEEK.dataChannelWithValues.result.timestamps), - options: ChartConfig.LINE_CHART_OPTIONS('day'), + options: ChartConfig.LINE_CHART_OPTIONS('day', 'line'), }, }); } @@ -64,7 +64,7 @@ describe('History Consumption', () => { DATA('Sonstiger: 683,3 kWh', [1.1707523832922395, 0.941219247423001, 0.9813072961027226, 0.9147731344893865, 0.9179723719850451, 1.0221279641612842, 0.966452725206484, 0.9473972354717355, 0.9621558239123786, 1.0389565290773752, 0.719602808727641, 0.7164739453418082, 0.8312551527306125, 1.0513294309882544, 1.0642356695090618, 1.064549904209455, 0.8827148020023398, 1.0886724659066331, 0.9617007570391821, 1.2024244259088868, 1.4752269957477093, 1.149323439144603, 1.2039544333297325, 1.0275239776315197, 0.9588534351033258, 1.0445672257542986, 1.1028960998629487, 0.9010854319660326, 0.8581094263176695, null, null]), ], labels: LABELS(History.MONTH.energyPerPeriodChannelWithValues.result.timestamps), - options: ChartConfig.BAR_CHART_OPTIONS('day'), + options: ChartConfig.BAR_CHART_OPTIONS('day', 'bar'), }, }); } @@ -81,7 +81,7 @@ describe('History Consumption', () => { DATA('Sonstiger: 10.883,9 kWh', [1275.767, 1390.6460000000002, 1480.519, 1565.359, 1387.424, 1027.67, 1412.9189999999999, 1344.913, 0, 0, 0, 0]), ], labels: LABELS(History.YEAR.energyPerPeriodChannelWithValues.result.timestamps), - options: ChartConfig.BAR_CHART_OPTIONS('month'), + options: ChartConfig.BAR_CHART_OPTIONS('month', 'bar'), }, }); } diff --git a/ui/src/app/edge/history/common/energy/chart/channels.spec.ts b/ui/src/app/edge/history/common/energy/chart/channels.spec.ts index 26842adba0a..8597a469099 100644 --- a/ui/src/app/edge/history/common/energy/chart/channels.spec.ts +++ b/ui/src/app/edge/history/common/energy/chart/channels.spec.ts @@ -7,183 +7,16 @@ import { QueryHistoricTimeseriesEnergyResponse } from "src/app/shared/jsonrpc/re export namespace History { - export const LINE_CHART_OPTIONS = (period: string): OeChartTester.Dataset.Option => ({ + export const LINE_CHART_OPTIONS = (period: string, chartType: 'line' | 'bar'): OeChartTester.Dataset.Option => ({ type: 'option', options: { - "maintainAspectRatio": false, - "legend": { - "labels": {}, - "position": "bottom", - }, - "elements": { - "point": { - "radius": 0, - "hitRadius": 0, - "hoverRadius": 0, - }, - "line": { - "borderWidth": 2, - "tension": 0.1, - }, - "rectangle": { - "borderWidth": 2, - }, - }, - "hover": { - "mode": "point", - "intersect": true, - }, - "scales": { - "yAxes": [ - { - "id": "left", - "position": "left", - "scaleLabel": { - "display": true, - "labelString": "kW", - "padding": 5, - "fontSize": 11, - }, - "gridLines": { - "display": true, - }, - "ticks": { - "beginAtZero": false, - }, - }, - { - "id": "right", - "position": "right", - "scaleLabel": { - "display": true, - "labelString": "%", - "padding": 10, - }, - "gridLines": { - "display": false, - }, - "ticks": { - "beginAtZero": true, - "max": 100, - "padding": 5, - "stepSize": 20, - }, - }, - ], - "xAxes": [ - { - "ticks": {}, - "stacked": false, - "type": "time", - "time": { - "minUnit": "hour", - "displayFormats": { - "millisecond": "SSS [ms]", - "second": "HH:mm:ss a", - "minute": "HH:mm", - "hour": "HH:[00]", - "day": "DD", - "week": "ll", - "month": "MM", - "quarter": "[Q]Q - YYYY", - "year": "YYYY", - }, - "unit": period as TimeUnit, - }, - "bounds": "ticks", - }, - ], - }, - "tooltips": { - "mode": "index", - "intersect": false, - "axis": "x", - "callbacks": {}, - }, - "responsive": true, + "responsive": true, "maintainAspectRatio": false, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "stepped": false, "fill": true } }, "datasets": { "bar": {}, "line": {} }, "plugins": { "colors": { "enabled": false }, "legend": { "display": true, "position": "bottom", "labels": { "color": '' } }, "tooltip": { "intersect": false, "mode": "index", "callbacks": {} } }, "scales": { "x": { "stacked": true, "offset": false, "type": "time", "ticks": { "source": "auto", "maxTicksLimit": 31 }, "bounds": "ticks", "adapters": { "date": { "locale": { "code": "de", "formatLong": {}, "localize": {}, "match": {}, "options": { "weekStartsOn": 1, "firstWeekContainsDate": 4 } } } }, "time": { "unit": period as TimeUnit, "displayFormats": { "datetime": "yyyy-MM-dd HH:mm:ss", "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:00", "day": "dd", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "yyyy" } } }, "left": { ...(chartType === 'line' ? { stacked: false } : {}), "title": { "text": "kW", "display": true, "padding": 5, "font": { "size": 11 } }, "position": "left", "grid": { "display": true }, "ticks": {} }, "right": { ...(chartType === 'line' ? { stacked: false } : {}), "beginAtZero": true, "max": 100, "min": 0, "type": "linear", "title": { "text": "%", "display": true, "font": { "size": 11 } }, "position": "right", "grid": { "display": false }, "ticks": { "padding": 5, "stepSize": 20 } } }, }, }); - export const BAR_CHART_OPTIONS = (period: string): OeChartTester.Dataset.Option => ({ + export const BAR_CHART_OPTIONS = (period: string, chartType: 'line' | 'bar'): OeChartTester.Dataset.Option => ({ type: 'option', options: { - "maintainAspectRatio": false, - "legend": { - "labels": {}, - "position": "bottom", - }, - "elements": { - "point": { - "radius": 0, - "hitRadius": 0, - "hoverRadius": 0, - }, - "line": { - "borderWidth": 2, - "tension": 0.1, - }, - "rectangle": { - "borderWidth": 2, - }, - }, - "hover": { - "mode": "point", - "intersect": true, - }, - "scales": { - "yAxes": [ - { - "id": "left", - "position": "left", - "scaleLabel": { - "display": true, - "labelString": "kWh", - "padding": 5, - "fontSize": 11, - }, - "gridLines": { - "display": true, - }, - "ticks": { - "beginAtZero": false, - }, - "stacked": true, - }, - ], - "xAxes": [ - { - "ticks": { - "maxTicksLimit": 12, - "source": "data", - }, - "stacked": true, - "type": "time", - "time": { - "minUnit": "hour", - "displayFormats": { - "millisecond": "SSS [ms]", - "second": "HH:mm:ss a", - "minute": "HH:mm", - "hour": "HH:[00]", - "day": "DD", - "week": "ll", - "month": "MM", - "quarter": "[Q]Q - YYYY", - "year": "YYYY", - }, - "unit": period as TimeUnit, - }, - "offset": true, - "bounds": "ticks", - }, - ], - }, - "tooltips": { - "mode": "x", - "intersect": false, - "axis": "x", - "callbacks": {}, - }, - "responsive": true, + "responsive": true, "maintainAspectRatio": false, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "stepped": false, "fill": true } }, "datasets": { "bar": { "barPercentage": 1 }, "line": {} }, "plugins": { "colors": { "enabled": false }, "legend": { "display": true, "position": "bottom", "labels": { "color": '' } }, "tooltip": { "intersect": false, "mode": "x", "callbacks": {} } }, "scales": { "x": { "stacked": true, "offset": true, "type": "time", "ticks": { "source": "auto", "maxTicksLimit": 31 }, "bounds": "ticks", "adapters": { "date": { "locale": { "code": "de", "formatLong": {}, "localize": {}, "match": {}, "options": { "weekStartsOn": 1, "firstWeekContainsDate": 4 } } } }, "time": { "unit": period as TimeUnit, "displayFormats": { "datetime": "yyyy-MM-dd HH:mm:ss", "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:00", "day": "dd", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "yyyy" } } }, "left": { ...(chartType === 'line' ? { stacked: false } : {}), "title": { "text": "kWh", "display": true, "padding": 5, "font": { "size": 11 } }, "position": "left", "grid": { "display": true }, "ticks": {} } }, }, }); diff --git a/ui/src/app/edge/history/common/energy/chart/chart.constants.spec.ts b/ui/src/app/edge/history/common/energy/chart/chart.constants.spec.ts index 03a34aae555..9828c860aca 100644 --- a/ui/src/app/edge/history/common/energy/chart/chart.constants.spec.ts +++ b/ui/src/app/edge/history/common/energy/chart/chart.constants.spec.ts @@ -9,7 +9,7 @@ import { ChartComponent } from "./chart"; export function expectView(config: EdgeConfig, testContext: TestContext, chartType: 'line' | 'bar', channels: OeTester.Types.Channels, view: OeChartTester.View): void { expect(removeFunctions(OeChartTester .apply(ChartComponent - .getChartData(DummyConfig.convertDummyEdgeConfigToRealEdgeConfig(config), chartType, testContext.translate), chartType, channels, testContext))) + .getChartData(DummyConfig.convertDummyEdgeConfigToRealEdgeConfig(config), chartType, testContext.translate), chartType, channels, testContext, config))) .toEqual(removeFunctions(view)); }; diff --git a/ui/src/app/edge/history/common/energy/chart/chart.spec.ts b/ui/src/app/edge/history/common/energy/chart/chart.spec.ts index e46dcb5c3a3..be77dd1532b 100644 --- a/ui/src/app/edge/history/common/energy/chart/chart.spec.ts +++ b/ui/src/app/edge/history/common/energy/chart/chart.spec.ts @@ -32,7 +32,7 @@ describe('History EnergyMonitor', () => { DATA('Ladezustand', History.DAY.dataChannelWithValues.result.data['_sum/EssSoc']), ], labels: LABELS(History.DAY.dataChannelWithValues.result.timestamps), - options: History.LINE_CHART_OPTIONS('hour'), + options: History.LINE_CHART_OPTIONS('hour', 'line'), }, }); @@ -54,7 +54,7 @@ describe('History EnergyMonitor', () => { DATA('Ladezustand', History.WEEK.dataChannelWithValues.result.data['_sum/EssSoc']), ], labels: LABELS(History.WEEK.dataChannelWithValues.result.timestamps), - options: History.LINE_CHART_OPTIONS('day'), + options: History.LINE_CHART_OPTIONS('day', 'line'), }, }); } @@ -77,7 +77,7 @@ describe('History EnergyMonitor', () => { DATA('Verbrauch: 9.976,1 kWh', [320.342, 346.615, 341.433, 333.054, 358.458, 347.872, 289.283, null, 556.51, 311.366, 314.722, 355.556, 381.671, 384.558, 366.19, 349.336, 303.696, 288.727, 357.434, 388.659, 402.625, null, 713.771, 320.238, 332.099, null, 756.429, 384.136, 371.322, null]), ], labels: LABELS(History.MONTH.energyPerPeriodChannelWithValues.result.timestamps), - options: History.BAR_CHART_OPTIONS('day'), + options: History.BAR_CHART_OPTIONS('day', 'bar'), }, }); } @@ -100,7 +100,7 @@ describe('History EnergyMonitor', () => { DATA('Verbrauch: 58.573,4 kWh', [11634.885, 8207.927, 8976.354, 8311.835, 10341.804, 9976.102, 975.807, null, null, null, null, null]), ], labels: LABELS(History.YEAR.energyPerPeriodChannelWithValues.result.timestamps), - options: History.BAR_CHART_OPTIONS('month'), + options: History.BAR_CHART_OPTIONS('month', 'bar'), }, }); } @@ -112,7 +112,7 @@ describe('History EnergyMonitor', () => { datasets: { data: [], labels: LABELS(History.YEAR.energyPerPeriodChannelWithValues.result.timestamps), - options: History.BAR_CHART_OPTIONS('month'), + options: History.BAR_CHART_OPTIONS('month', 'bar'), }, }); } @@ -135,7 +135,7 @@ describe('History EnergyMonitor', () => { DATA('Verbrauch: 58.573,4 kWh', [11634.885, 8207.927, 8976.354, 8311.835, 10341.804, 9976.102, 975.807, null, null, null, null, null]), ], labels: LABELS(History.YEAR.energyPerPeriodChannelWithValues.result.timestamps), - options: History.BAR_CHART_OPTIONS('month'), + options: History.BAR_CHART_OPTIONS('month', 'bar'), }, }); } @@ -155,7 +155,7 @@ describe('History EnergyMonitor', () => { DATA('Verbrauch: 58.573,4 kWh', [11634.885, 8207.927, 8976.354, 8311.835, 10341.804, 9976.102, 975.807, null, null, null, null, null]), ], labels: LABELS(History.YEAR.energyPerPeriodChannelWithValues.result.timestamps), - options: History.BAR_CHART_OPTIONS('month'), + options: History.BAR_CHART_OPTIONS('month', 'bar'), }, }); } @@ -175,7 +175,7 @@ describe('History EnergyMonitor', () => { DATA('Verbrauch: 58.573,4 kWh', [11634.885, 8207.927, 8976.354, 8311.835, 10341.804, 9976.102, 975.807, null, null, null, null, null]), ], labels: LABELS(History.YEAR.energyPerPeriodChannelWithValues.result.timestamps), - options: History.BAR_CHART_OPTIONS('month'), + options: History.BAR_CHART_OPTIONS('month', 'bar'), }, }); } diff --git a/ui/src/app/edge/history/common/energy/chart/chart.ts b/ui/src/app/edge/history/common/energy/chart/chart.ts index f6b7d64e835..505419d20fd 100644 --- a/ui/src/app/edge/history/common/energy/chart/chart.ts +++ b/ui/src/app/edge/history/common/energy/chart/chart.ts @@ -193,7 +193,9 @@ export class ChartComponent extends AbstractHistoryChart { borderDash: [10, 10], yAxisId: ChartAxis.RIGHT, stack: 1, - customUnit: YAxisTitle.PERCENTAGE, + custom: { + unit: YAxisTitle.PERCENTAGE, + }, }], ]; }, diff --git a/ui/src/app/edge/history/common/grid/chart/chart.constants.spec.ts b/ui/src/app/edge/history/common/grid/chart/chart.constants.spec.ts index 75fc71de268..d53747d4ab1 100644 --- a/ui/src/app/edge/history/common/grid/chart/chart.constants.spec.ts +++ b/ui/src/app/edge/history/common/grid/chart/chart.constants.spec.ts @@ -2,12 +2,13 @@ import { DummyConfig } from "src/app/shared/edge/edgeconfig.spec"; import { OeTester } from "src/app/shared/genericComponents/shared/testing/common"; import { OeChartTester } from "src/app/shared/genericComponents/shared/testing/tester"; import { EdgeConfig } from "src/app/shared/shared"; -import { TestContext, removeFunctions } from "src/app/shared/test/utils.spec"; +import { removeFunctions, TestContext } from "src/app/shared/test/utils.spec"; + import { ChartComponent } from "./chart"; export function expectView(config: EdgeConfig, testContext: TestContext, chartType: 'line' | 'bar', channels: OeTester.Types.Channels, view: OeChartTester.View, showPhases: boolean): void { expect(removeFunctions(OeChartTester .apply(ChartComponent - .getChartData(DummyConfig.convertDummyEdgeConfigToRealEdgeConfig(config), chartType, testContext.translate, showPhases), chartType, channels, testContext))) + .getChartData(DummyConfig.convertDummyEdgeConfigToRealEdgeConfig(config), chartType, testContext.translate, showPhases), chartType, channels, testContext, config))) .toEqual(removeFunctions(view)); }; diff --git a/ui/src/app/edge/history/common/grid/chart/chart.spec.ts b/ui/src/app/edge/history/common/grid/chart/chart.spec.ts index 644eb2d84c2..d4971e1d400 100644 --- a/ui/src/app/edge/history/common/grid/chart/chart.spec.ts +++ b/ui/src/app/edge/history/common/grid/chart/chart.spec.ts @@ -27,7 +27,7 @@ describe('History Grid', () => { DATA('Bezug: 0,9 kWh', [null, null, null, 0.031, 0.018, 0, 0.02, 0.016, 0.015, 0.014, 0.009, 0.02, 0.025, 0.025, 0.025, 0.021, 0.012, 0.009, 0.01, 0.011, 0.005, 0.003, 0, 0.015, 0.018, 0.023, 0, 0, 0, 0.002, 0.002, 0.003, 0.015, 0.008, 0.022, 0.027, 0.016, 0.003, 0.002, 0, 0.028, 0.027, 0.017, 0.001, 0, 0, 0, null, null, null, null, 0.011, 0.01, 0.004, 0.006, 0.007, 0.018, 0.008, 0.012, 0.009, 0.004, 0.013, 0.015, 0.012, 0, 0, 0, 0.002, 0, 0.005, 0.001, 0.03, 0.062, 0, 0, 0, 0, 0, 0, 0, 0, 0.015, 0.005, 0.004, 0.007, 0, 0, 0, 0, 0, 0, 0, 0.005, 0, 0, 0, 0, 0, 0, 0.021, 0, 0, 0, 0, 0, 0.003, 0, 0.004, 0, 0, 0.032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]), ], labels: LABELS(History.DAY.dataChannelWithValues.result.timestamps), - options: OeTester.ChartOptions.LINE_CHART_OPTIONS('hour'), + options: OeTester.ChartOptions.LINE_CHART_OPTIONS('hour', 'line'), }, }, false); } @@ -41,7 +41,7 @@ describe('History Grid', () => { DATA('Bezug: 2,4 kWh', [0, 0.011916666666666666, 0.01633333333333333, 0.00609090909090909, 0.015333333333333334, 0.011666666666666665, 0.0024166666666666664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.02425, 0.004416666666666667, 0.0035833333333333333, 0, 0, 0, 0.04441666666666667, 0, 0.013111111111111112, 0.001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0011666666666666668, 0, 0, 0, 0.0015833333333333333, 0.013333333333333334, 0.020416666666666666, 0.01125, 0.019727272727272725, 0.012444444444444445, 0.009583333333333334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.007666666666666667, 0, 0.0023333333333333335, 0.0125, 0.01609090909090909, 0.02016666666666667, 0.014083333333333333, 0.006363636363636363, 0.01955555555555556, 0.04841666666666666, 0.011166666666666667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.014222222222222221, 0.00225, 0, 0.0036666666666666666, 0.032916666666666664, 0.014666666666666666, 0.0135, 0.017363636363636362, 0.013333333333333334, 0.022083333333333333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0009166666666666666, 0, 0.0021666666666666666, 0, 0, 0, 0.0005, 0.04841666666666666, 0, 0.005555555555555556, 0.02716666666666667, 0.017333333333333333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0023333333333333335, 0.008333333333333333, 0.003, 0.015916666666666666, 0.00325, 0, 0.004333333333333333, 0.001, 0, 0, 0.019545454545454546, 0.0017777777777777776, 0.006416666666666667, 0.017666666666666667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0058, 0.005625, 0, 0]), ], labels: LABELS(History.WEEK.dataChannelWithValues.result.timestamps), - options: OeTester.ChartOptions.LINE_CHART_OPTIONS('day'), + options: OeTester.ChartOptions.LINE_CHART_OPTIONS('day', 'line'), }, }, false); @@ -56,13 +56,13 @@ describe('History Grid', () => { DATA('Bezug: 773 kWh', [16, 6, 3, 3, 5, 48, 4, null, 5, 26, 17, 62, 8, 66, 13, 21, 4, 3, 18, 27, 29, null, 118, 85, 2, null, 72, 28, 84, null]), ], labels: LABELS(History.MONTH.energyPerPeriodChannelWithValues.result.timestamps), - options: OeTester.ChartOptions.BAR_CHART_OPTIONS('day'), + options: OeTester.ChartOptions.BAR_CHART_OPTIONS('day', 'bar'), }, }, false); } { - // Line - Chart + // BAR - Chart expectView(defaultEMS, TEST_CONTEXT, 'bar', History.YEAR, { datasets: { @@ -71,7 +71,7 @@ describe('History Grid', () => { DATA('Bezug: 23.209 kWh', [9829, 4812, 2915, 2036, 2712, 773, 94, null, null, null, null, null]), ], labels: LABELS(History.YEAR.energyPerPeriodChannelWithValues.result.timestamps), - options: OeTester.ChartOptions.BAR_CHART_OPTIONS('month'), + options: OeTester.ChartOptions.BAR_CHART_OPTIONS('month', 'bar'), }, }, false); } diff --git a/ui/src/app/edge/history/delayedselltogrid/chart.component.ts b/ui/src/app/edge/history/delayedselltogrid/chart.component.ts index 968cf66b11d..f0821e6b4b1 100644 --- a/ui/src/app/edge/history/delayedselltogrid/chart.component.ts +++ b/ui/src/app/edge/history/delayedselltogrid/chart.component.ts @@ -1,12 +1,11 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from './../shared'; @Component({ selector: 'delayedselltogridgchart', @@ -187,6 +186,9 @@ export class DelayedSellToGridChartComponent extends AbstractHistoryChart implem console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(() => { + this.unit = YAxisTitle.ENERGY; + this.setOptions(this.options); }); } @@ -204,14 +206,7 @@ export class DelayedSellToGridChartComponent extends AbstractHistoryChart implem } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - }; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/fixdigitaloutput/singlechart.component.ts b/ui/src/app/edge/history/fixdigitaloutput/singlechart.component.ts index e317aed5dae..2b18cf58c53 100644 --- a/ui/src/app/edge/history/fixdigitaloutput/singlechart.component.ts +++ b/ui/src/app/edge/history/fixdigitaloutput/singlechart.component.ts @@ -1,13 +1,13 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { YAxisTitle } from 'src/app/shared/service/utils'; import { QueryHistoricTimeseriesDataResponse } from '../../../shared/jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'fixDigitalOutputSingleChart', @@ -54,7 +54,7 @@ export class FixDigitalOutputSingleChartComponent extends AbstractHistoryChart i this.labels = labels; // convert datasets - let datasets = []; + let datasets: Chart.ChartDataset[] = []; for (let channel in result.data) { let address = ChannelAddress.fromString(channel); let data = result.data[channel].map(value => { @@ -76,11 +76,14 @@ export class FixDigitalOutputSingleChartComponent extends AbstractHistoryChart i this.datasets = datasets; this.loading = false; this.stopSpinner(); - }).catch(reason => { console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + this.unit = YAxisTitle.PERCENTAGE; + await this.setOptions(this.options); + this.stopSpinner(); }); } @@ -93,15 +96,7 @@ export class FixDigitalOutputSingleChartComponent extends AbstractHistoryChart i } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = this.translate.instant('General.percentage'); - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; // TODO get locale dynamically - }; - options.scales.yAxes[0].ticks.max = 100; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/fixdigitaloutput/totalchart.component.ts b/ui/src/app/edge/history/fixdigitaloutput/totalchart.component.ts index 8e292f50f9b..190b6f82a01 100644 --- a/ui/src/app/edge/history/fixdigitaloutput/totalchart.component.ts +++ b/ui/src/app/edge/history/fixdigitaloutput/totalchart.component.ts @@ -1,13 +1,12 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { YAxisTitle } from 'src/app/shared/service/utils'; import { QueryHistoricTimeseriesDataResponse } from '../../../shared/jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { ChannelAddress, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'fixDigitalOutputTotalChart', @@ -57,7 +56,7 @@ export class FixDigitalOutputTotalChartComponent extends AbstractHistoryChart im // convert datasets Object.keys(result.data).forEach((channel, index) => { let address = ChannelAddress.fromString(channel); - let data = result.data[channel].map((value) => { + let data = result.data[channel]?.map((value) => { if (value == null) { return null; } else { @@ -95,6 +94,10 @@ export class FixDigitalOutputTotalChartComponent extends AbstractHistoryChart im console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + this.unit = YAxisTitle.PERCENTAGE; + this.formatNumber = '1.0-0'; + await this.setOptions(this.options); }); } @@ -113,15 +116,7 @@ export class FixDigitalOutputTotalChartComponent extends AbstractHistoryChart im } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = this.translate.instant('General.percentage'); - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; // TODO get locale dynamically - }; - options.scales.yAxes[0].ticks.max = 100; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/grid/chart.component.ts b/ui/src/app/edge/history/grid/chart.component.ts index 55394a463a4..4f45266f9d0 100644 --- a/ui/src/app/edge/history/grid/chart.component.ts +++ b/ui/src/app/edge/history/grid/chart.component.ts @@ -6,7 +6,7 @@ import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from './../shared'; +import * as Chart from 'chart.js'; @Component({ selector: 'gridChart', @@ -166,10 +166,9 @@ export class GridChartComponent extends AbstractHistoryChart implements OnInit, protected setLabel() { let translate = this.translate; // enables access to TranslateService let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; + options.plugins.tooltip.callbacks.label = function (tooltipItem: Chart.TooltipItem) { + let label = tooltipItem.dataset.label; + let value = tooltipItem.dataset.data[tooltipItem.dataIndex]; // 0.005 to prevent showing Charge or Discharge if value is e.g. 0.00232138 if (value < -0.005) { if (label.includes(translate.instant('General.phase'))) { diff --git a/ui/src/app/edge/history/gridoptimizedcharge/chart.component.ts b/ui/src/app/edge/history/gridoptimizedcharge/chart.component.ts index f0c68474dad..f1e3b5df05b 100644 --- a/ui/src/app/edge/history/gridoptimizedcharge/chart.component.ts +++ b/ui/src/app/edge/history/gridoptimizedcharge/chart.component.ts @@ -1,14 +1,13 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { differenceInDays } from 'date-fns'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { ChartAxis, HistoryUtils, YAxisTitle } from 'src/app/shared/service/utils'; +import { AbstractHistoryChart as NewAbstractHistoryChart } from '../../../shared/genericComponents/chart/abstracthistorychart'; import { QueryHistoricTimeseriesDataResponse } from '../../../shared/jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { ChannelAddress, EdgeConfig, Service, Utils } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { ChartOptions, Data, DEFAULT_TIME_CHART_OPTIONS, TooltipItem } from '../shared'; @Component({ selector: 'gridOptimizedChargeChart', @@ -183,6 +182,31 @@ export class GridOptimizedChargeChartComponent extends AbstractHistoryChart impl console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + await this.setOptions(this.options); + this.applyControllerSpecificOptions(); + }); + } + + private applyControllerSpecificOptions() { + const yAxis: HistoryUtils.yAxes = { + unit: YAxisTitle.PERCENTAGE, + position: 'right', + yAxisId: ChartAxis.RIGHT, + displayGrid: false, + }; + + const locale = this.service.translate.currentLang; + this.options = NewAbstractHistoryChart.getYAxisOptions(this.options, yAxis, this.translate, 'line', locale); + + this.datasets = this.datasets.map((el, index, arr) => { + + // align last element to right yAxis + if ((arr.length - 1) === index) { + el['yAxisID'] = ChartAxis.RIGHT; + } + + return el; }); } @@ -203,68 +227,10 @@ export class GridOptimizedChargeChartComponent extends AbstractHistoryChart impl } protected setLabel() { - let translate = this.translate; - let options = Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS); - // adds second y-axis to chart - options.scales.yAxes.push({ - id: 'yAxis2', - position: 'right', - scaleLabel: { - display: true, - labelString: "%", - padding: -2, - fontSize: 11, - }, - gridLines: { - display: false, - }, - ticks: { - beginAtZero: true, - max: 100, - padding: -5, - stepSize: 20, - }, - }); - options.layout = { - padding: { - left: 2, - right: 2, - top: 0, - bottom: 0, - }, - }; - //x-axis - if (differenceInDays(this.service.historyPeriod.value.to, this.service.historyPeriod.value.from) >= 5) { - options.scales.xAxes[0].time.unit = "day"; - } else { - options.scales.xAxes[0].time.unit = "hour"; - } - - //y-axis - options.scales.yAxes[0].id = "yAxis1"; - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.scales.yAxes[0].scaleLabel.padding = -2; - options.scales.yAxes[0].scaleLabel.fontSize = 11; - options.scales.yAxes[0].ticks.padding = -5; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - if (label.split(" ").length > 1) { - label = label.split(" ").slice(0, 1).toString(); - - } - - let value = tooltipItem.yLabel; - if (label == translate.instant('General.soc')) { - return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; - } else { - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - } - }; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { return window.innerHeight / 21 * 9; } - } diff --git a/ui/src/app/edge/history/gridoptimizedcharge/sellToGridLimitChart.component.ts b/ui/src/app/edge/history/gridoptimizedcharge/sellToGridLimitChart.component.ts index ad807241796..d8b2c4ebaa8 100644 --- a/ui/src/app/edge/history/gridoptimizedcharge/sellToGridLimitChart.component.ts +++ b/ui/src/app/edge/history/gridoptimizedcharge/sellToGridLimitChart.component.ts @@ -1,4 +1,3 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -7,7 +6,6 @@ import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; import { QueryHistoricTimeseriesDataResponse } from '../../../shared/jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { ChannelAddress, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'sellToGridLimitChart', @@ -173,6 +171,8 @@ export class SellToGridLimitChartComponent extends AbstractHistoryChart implemen console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + await this.setOptions(this.options); }); } @@ -191,19 +191,11 @@ export class SellToGridLimitChartComponent extends AbstractHistoryChart implemen } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - }; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { //return window.innerHeight / 1.3; return window.innerHeight / 21 * 9; } - } diff --git a/ui/src/app/edge/history/heatingelement/chart.component.ts b/ui/src/app/edge/history/heatingelement/chart.component.ts index 21487bc3a69..8c8483c6bca 100644 --- a/ui/src/app/edge/history/heatingelement/chart.component.ts +++ b/ui/src/app/edge/history/heatingelement/chart.component.ts @@ -1,13 +1,14 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; + +import type { ChartOptions } from 'chart.js'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { ChartAxis, YAxisTitle } from 'src/app/shared/service/utils'; import { QueryHistoricTimeseriesDataResponse } from '../../../shared/jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'heatingelementChart', @@ -90,7 +91,12 @@ export class HeatingelementChartComponent extends AbstractHistoryChart implement console.error(reason); // TODO error message this.initializeChart(); return; - }); + }).finally(async () => { + this.formatNumber = '1.0-1'; + this.unit = YAxisTitle.NONE; + await this.setOptions(this.options); + this.applyControllerSpecificOptions(this.options); + });; } protected getChannelAddresses(edge: Edge, config: EdgeConfig): Promise { @@ -101,21 +107,19 @@ export class HeatingelementChartComponent extends AbstractHistoryChart implement }); } - protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].id = 'yAxis1'; - options.scales.yAxes[0].scaleLabel.labelString = 'Level'; - options.scales.yAxes[0].ticks.beginAtZero = true; - options.scales.yAxes[0].ticks.max = 3; - options.scales.yAxes[0].ticks.stepSize = 1; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-1'); // TODO get locale dynamically - }; + protected applyControllerSpecificOptions(options: ChartOptions) { + const translate = this.translate; + options.scales[ChartAxis.LEFT]['title'].text = 'Level'; + options.scales[ChartAxis.LEFT]['beginAtZero'] = true; + options.scales[ChartAxis.LEFT].max = 3; + options.scales[ChartAxis.LEFT].ticks['stepSize'] = 1; this.options = options; } + protected setLabel() { + this.options = this.createDefaultChartOptions(); + } + public getChartHeight(): number { return window.innerHeight / 1.3; } diff --git a/ui/src/app/edge/history/heatpump/chart.component.ts b/ui/src/app/edge/history/heatpump/chart.component.ts index 54d299505d8..d193aad1e96 100644 --- a/ui/src/app/edge/history/heatpump/chart.component.ts +++ b/ui/src/app/edge/history/heatpump/chart.component.ts @@ -1,11 +1,12 @@ import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { ChartAxis } from 'src/app/shared/service/utils'; import { ChannelAddress, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from './../shared'; @Component({ selector: 'heatpumpchart', @@ -76,12 +77,15 @@ export class HeatPumpChartComponent extends AbstractHistoryChart implements OnIn } this.datasets = datasets; this.loading = false; - this.stopSpinner(); }).catch(reason => { console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + await this.setOptions(this.options); + this.applyControllerSpecificOptions(this.options); + this.stopSpinner(); }); } @@ -91,12 +95,10 @@ export class HeatPumpChartComponent extends AbstractHistoryChart implements OnIn }); } - protected setLabel() { - let options = this.createDefaultChartOptions(); + private applyControllerSpecificOptions(options: Chart.ChartOptions) { let translate = this.translate; - options.scales.yAxes[0].id = 'yAxis1'; - options.scales.yAxes[0].scaleLabel.labelString = this.translate.instant('General.state'); - options.scales.yAxes[0].ticks.callback = function (label, index, labels) { + options.scales[ChartAxis.LEFT]['title'].text = this.translate.instant('General.state'); + options.scales[ChartAxis.LEFT].ticks.callback = function (label, index, labels) { switch (label) { case -1: return translate.instant('Edge.Index.Widgets.HeatPump.undefined'); @@ -110,11 +112,10 @@ export class HeatPumpChartComponent extends AbstractHistoryChart implements OnIn return translate.instant('Edge.Index.Widgets.HeatPump.switchOnComShort'); } }; - options.scales.yAxes[0].ticks.max = 3; - options.scales.yAxes[0].ticks.stepSize = 1; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; + + options.plugins.tooltip.callbacks.label = function (tooltipItem: Chart.TooltipItem) { + let label = tooltipItem.dataset.label; + let value = tooltipItem.dataset.data[tooltipItem.dataIndex]; let toolTipValue; switch (value) { case -1: @@ -139,9 +140,16 @@ export class HeatPumpChartComponent extends AbstractHistoryChart implements OnIn } return label + ": " + toolTipValue; // TODO get locale dynamically }; + + options.scales[ChartAxis.LEFT].max = 3; + options.scales[ChartAxis.LEFT]['beginAtZero'] = true; this.options = options; } + protected setLabel() { + this.options = this.createDefaultChartOptions(); + } + public getChartHeight(): number { return window.innerHeight / 1.3; } diff --git a/ui/src/app/edge/history/peakshaving/asymmetric/chart.component.ts b/ui/src/app/edge/history/peakshaving/asymmetric/chart.component.ts index 295715c5efe..69f67dfa923 100644 --- a/ui/src/app/edge/history/peakshaving/asymmetric/chart.component.ts +++ b/ui/src/app/edge/history/peakshaving/asymmetric/chart.component.ts @@ -1,12 +1,11 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from '../../../../shared/shared'; import { AbstractHistoryChart } from '../../abstracthistorychart'; -import { Data, TooltipItem } from './../../shared'; @Component({ selector: 'asymmetricpeakshavingchart', @@ -211,7 +210,11 @@ export class AsymmetricPeakshavingChartComponent extends AbstractHistoryChart im console.error(reason); // TODO error message this.initializeChart(); return; - }); + }).finally(async () => { + this.unit = YAxisTitle.ENERGY; + await this.setOptions(this.options); + this.stopSpinner(); + });; } protected getChannelAddresses(edge: Edge, config: EdgeConfig): Promise { @@ -230,14 +233,7 @@ export class AsymmetricPeakshavingChartComponent extends AbstractHistoryChart im } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - }; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/peakshaving/symmetric/chart.component.ts b/ui/src/app/edge/history/peakshaving/symmetric/chart.component.ts index 5ad97470eec..c506f522217 100644 --- a/ui/src/app/edge/history/peakshaving/symmetric/chart.component.ts +++ b/ui/src/app/edge/history/peakshaving/symmetric/chart.component.ts @@ -1,4 +1,3 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -6,7 +5,6 @@ import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from '../../../../shared/shared'; import { AbstractHistoryChart } from '../../abstracthistorychart'; -import { Data, TooltipItem } from './../../shared'; @Component({ selector: 'symmetricpeakshavingchart', @@ -187,6 +185,8 @@ export class SymmetricPeakshavingChartComponent extends AbstractHistoryChart imp console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + await this.setOptions(this.options); }); } @@ -205,12 +205,6 @@ export class SymmetricPeakshavingChartComponent extends AbstractHistoryChart imp protected setLabel() { let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - }; this.options = options; } diff --git a/ui/src/app/edge/history/peakshaving/timeslot/chart.component.ts b/ui/src/app/edge/history/peakshaving/timeslot/chart.component.ts index f86a1a34117..85f08d061c4 100644 --- a/ui/src/app/edge/history/peakshaving/timeslot/chart.component.ts +++ b/ui/src/app/edge/history/peakshaving/timeslot/chart.component.ts @@ -1,12 +1,11 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from '../../../../shared/shared'; import { AbstractHistoryChart } from '../../abstracthistorychart'; -import { Data, TooltipItem } from './../../shared'; @Component({ selector: 'timeslotpeakshavingchart', @@ -200,7 +199,10 @@ export class TimeslotPeakshavingChartComponent extends AbstractHistoryChart impl console.error(reason); // TODO error message this.initializeChart(); return; - }); + }).finally(async () => { + this.unit = YAxisTitle.ENERGY; + await this.setOptions(this.options); + });; } protected getChannelAddresses(edge: Edge, config: EdgeConfig): Promise { @@ -218,14 +220,7 @@ export class TimeslotPeakshavingChartComponent extends AbstractHistoryChart impl } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - }; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/shared.ts b/ui/src/app/edge/history/shared.ts index 3a09ce17541..87d578f2e63 100644 --- a/ui/src/app/edge/history/shared.ts +++ b/ui/src/app/edge/history/shared.ts @@ -1,7 +1,9 @@ -import { ChartLegendLabelItem, ChartTooltipItem } from 'chart.js'; +import * as Chart from 'chart.js'; import { differenceInDays, differenceInMinutes, startOfDay } from 'date-fns'; +import { de } from 'date-fns/locale'; import { QueryHistoricTimeseriesDataResponse } from 'src/app/shared/jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { ChannelAddress, Service } from 'src/app/shared/shared'; +import { DateUtils } from 'src/app/shared/utils/date/dateutils'; export interface Dataset { label: string; @@ -61,6 +63,7 @@ export type YAxis = { } export type ChartOptions = { + plugins: {}, layout?: { padding: { left: number, @@ -69,13 +72,14 @@ export type ChartOptions = { bottom: number } } + datasets: {}, responsive?: boolean, maintainAspectRatio: boolean, legend: { - onClick?(event: MouseEvent, legendItem: ChartLegendLabelItem): void + onClick?(event: MouseEvent, legendItem: Chart.LegendItem): void labels: { - generateLabels?(chart: Chart): ChartLegendLabelItem[], - filter?(legendItem: ChartLegendLabelItem, data: ChartData): any, + generateLabels?(chart: Chart.Chart): Chart.LegendItem[], + filter?(legendItem: Chart.LegendItem, data: ChartData): any, }, position: "bottom" }, @@ -130,23 +134,20 @@ export type ChartOptions = { mode: string, intersect: boolean, axis: string, - itemSort?(itemA: ChartTooltipItem, itemB: ChartTooltipItem, data?: ChartData): number, + itemSort?(itemA: Chart.TooltipItem, itemB: Chart.TooltipItem, data?: ChartData): number, callbacks: { label?(tooltipItem: TooltipItem, data: Data): string, - title?(tooltipItems: TooltipItem[], data: Data): string, - afterTitle?(item: ChartTooltipItem[], data: Data): string | string[], - footer?(item: ChartTooltipItem[], data: ChartData): string | string[] + title?(tooltipItems: Chart.TooltipItem[], data: Data): string, + afterTitle?(item: Chart.TooltipItem[], data: Data): string | string[], + footer?(item: Chart.TooltipItem[], data: ChartData): string | string[] } }, - legendCallback?(chart: Chart): string + legendCallback?(chart: Chart.Chart): string } -export const DEFAULT_TIME_CHART_OPTIONS: ChartOptions = { +export const DEFAULT_TIME_CHART_OPTIONS: Chart.ChartOptions = { + responsive: true, maintainAspectRatio: false, - legend: { - labels: {}, - position: 'bottom', - }, elements: { point: { radius: 0, @@ -154,62 +155,85 @@ export const DEFAULT_TIME_CHART_OPTIONS: ChartOptions = { hoverRadius: 0, }, line: { - borderWidth: 2, - tension: 0.1, - }, - rectangle: { - borderWidth: 2, + stepped: false, + fill: true, }, }, - hover: { - mode: 'point', - intersect: true, + datasets: { + bar: {}, + line: {}, }, - scales: { - yAxes: [{ - position: 'left', - scaleLabel: { - display: true, - labelString: "", + plugins: { + colors: { + enabled: false, + }, + legend: { + display: true, + + position: 'bottom', + labels: { + color: getComputedStyle(document.documentElement).getPropertyValue('--ion-color-primary'), + generateLabels: (chart: Chart.Chart) => { return null; }, }, - ticks: { - beginAtZero: true, + onClick: (event, legendItem, legend) => { }, + }, + tooltip: { + intersect: false, + mode: 'index', + filter: function (item, data, test, some) { + const value = item.dataset.data[item.dataIndex] as number; + return !isNaN(value) && value !== null; }, - }], - xAxes: [{ - ticks: {}, - stacked: false, + callbacks: { + label: (item: Chart.TooltipItem) => { }, + title: (tooltipItems: Chart.TooltipItem[]) => { }, + afterTitle: (items: Chart.TooltipItem[]) => { }, + labelColor: (context: Chart.TooltipItem) => { }, + }, + }, + }, + scales: { + x: { + stacked: true, + offset: false, type: 'time', + ticks: { + }, + bounds: 'data', + adapters: { + date: { + + // TODO: get current locale + locale: de, + }, + }, time: { - minUnit: 'hour', + // parser: 'MM/DD/YYYY HH:mm', + unit: 'hour', displayFormats: { + datetime: 'yyyy-MM-dd HH:mm:ss', millisecond: 'SSS [ms]', second: 'HH:mm:ss a', // 17:20:01 minute: 'HH:mm', // 17:20 - hour: 'HH:[00]', // 17:20 - day: 'DD', // Sep 04 2015 + hour: 'HH:00', // 17:20 + day: 'dd', // Sep 04 2015 week: 'll', // Week 46, or maybe "[W]WW - YYYY" ? month: 'MM', // September quarter: '[Q]Q - YYYY', // Q3 - 2015 - year: 'YYYY', // 2015, + year: 'yyyy', // 2015, }, }, - }], - }, - tooltips: { - mode: 'index', - intersect: false, - axis: 'x', - callbacks: { - title(tooltipItems: TooltipItem[], data: Data): string { - let date = new Date(tooltipItems[0].xLabel); - return date.toLocaleDateString() + " " + date.toLocaleTimeString(); - }, }, }, }; export const DEFAULT_TIME_CHART_OPTIONS_WITHOUT_PREDEFINED_Y_AXIS: ChartOptions = { + plugins: { + legend: { + labels: {}, + }, + }, + datasets: {}, maintainAspectRatio: false, legend: { labels: {}, @@ -260,8 +284,8 @@ export const DEFAULT_TIME_CHART_OPTIONS_WITHOUT_PREDEFINED_Y_AXIS: ChartOptions intersect: false, axis: 'x', callbacks: { - title(tooltipItems: TooltipItem[], data: Data): string { - let date = new Date(tooltipItems[0].xLabel); + title(tooltipItems: Chart.TooltipItem[], data: Data): string { + let date = DateUtils.stringToDate(tooltipItems[0]?.label); return date.toLocaleDateString() + " " + date.toLocaleTimeString(); }, }, diff --git a/ui/src/app/edge/history/singlethreshold/chart.component.ts b/ui/src/app/edge/history/singlethreshold/chart.component.ts index 00f06db98cd..8717442adfa 100644 --- a/ui/src/app/edge/history/singlethreshold/chart.component.ts +++ b/ui/src/app/edge/history/singlethreshold/chart.component.ts @@ -2,12 +2,13 @@ import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { ChartAxis, YAxisTitle } from 'src/app/shared/service/utils'; import { QueryHistoricTimeseriesDataResponse } from '../../../shared/jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'singlethresholdChart', @@ -143,6 +144,7 @@ export class SinglethresholdChartComponent extends AbstractHistoryChart implemen hidden: false, yAxisID: yAxisID, position: 'right', + unit: YAxisTitle.PERCENTAGE, }); this.colors.push({ @@ -173,8 +175,11 @@ export class SinglethresholdChartComponent extends AbstractHistoryChart implemen console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + this.unit = YAxisTitle.PERCENTAGE; + await this.setOptions(this.options); + this.addControllerSpecificOptions(this.options); }); - }).catch(reason => { console.error(reason); // TODO error message this.initializeChart(); @@ -197,64 +202,69 @@ export class SinglethresholdChartComponent extends AbstractHistoryChart implemen } protected setLabel(config: EdgeConfig) { - let inputChannel = ChannelAddress.fromString(config.getComponentProperties(this.componentId)['inputChannelAddress']); - let outputChannelAddress: string | string[] = config.getComponentProperties(this.componentId)['outputChannelAddress']; - let outputChannel: ChannelAddress; - if (typeof outputChannelAddress === 'string') { - outputChannel = ChannelAddress.fromString(outputChannelAddress); - } else { - outputChannel = ChannelAddress.fromString(outputChannelAddress[0]); - } - let labelString; - let options = this.createDefaultChartOptions(); - let translate = this.translate; + this.options = this.createDefaultChartOptions(); + } - if (inputChannel.channelId == 'EssSoc') { - labelString = '%'; - options.scales.yAxes[0].id = "yAxis1"; - options.scales.yAxes[0].scaleLabel.labelString = labelString; - } else if (inputChannel.channelId == 'GridActivePower' || inputChannel.channelId == 'ProductionActivePower') { - labelString = 'kW'; - options.scales.yAxes[0].id = "yAxis1"; - options.scales.yAxes[0].scaleLabel.labelString = labelString; - } else { - labelString = config.getChannel(inputChannel)['unit']; - options.scales.yAxes[0].id = "yAxis1"; - options.scales.yAxes[0].scaleLabel.labelString = labelString; - } + protected addControllerSpecificOptions(options: Chart.ChartOptions) { - if (inputChannel.channelId != 'EssSoc') { - // adds second y-axis to chart - options.scales.yAxes.push({ - id: 'yAxis2', - position: 'right', - scaleLabel: { - display: true, - labelString: "%", - }, - gridLines: { - display: false, - }, - ticks: { - beginAtZero: true, - max: 100, - padding: -5, - stepSize: 20, - }, - }); - } - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - if (label == outputChannel.channelId || label == translate.instant('General.soc')) { - return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; - } else if (label == translate.instant('General.grid') || label == translate.instant('General.production')) { - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; + this.service.getConfig().then(config => { + + let inputChannel = ChannelAddress.fromString(config.getComponentProperties(this.componentId)['inputChannelAddress']); + let outputChannelAddress: string | string[] = config.getComponentProperties(this.componentId)['outputChannelAddress']; + let outputChannel: ChannelAddress; + if (typeof outputChannelAddress === 'string') { + outputChannel = ChannelAddress.fromString(outputChannelAddress); + } else { + outputChannel = ChannelAddress.fromString(outputChannelAddress[0]); + } + + let labelString; + + if (inputChannel.channelId == 'EssSoc') { + labelString = '%'; + this.unit = YAxisTitle.PERCENTAGE; + options.scales[ChartAxis.LEFT]['title'].text = labelString; + } else if (inputChannel.channelId == 'GridActivePower' || inputChannel.channelId == 'ProductionActivePower') { + labelString = 'kW'; + this.unit = YAxisTitle.ENERGY; + options.scales[ChartAxis.LEFT]['title'].text = labelString; } else { - return label + ": " + formatNumber(value, 'de', '1.0-2') + " " + labelString; + labelString = config.getChannel(inputChannel)['unit']; + options.scales[ChartAxis.LEFT]['title'].text = labelString; } - }; - this.options = options; + + if (inputChannel.channelId != 'EssSoc') { + // adds second y-axis to chart + options.scales[ChartAxis.RIGHT] = { + max: 100, + position: 'right', + title: { + text: '%', + display: true, + }, + ticks: { + padding: -5, + stepSize: 20, + }, + }; + } + + let translate = this.translate; + options.plugins.tooltip.callbacks.label = function (item: Chart.TooltipItem) { + let label = item.dataset.label; + let value = item.dataset.data[item.dataIndex]; + if (label == outputChannel.channelId || label == translate.instant('General.soc')) { + return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; + } else if (label == translate.instant('General.grid') || label == translate.instant('General.production')) { + return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; + } else { + return label + ": " + formatNumber(value, 'de', '1.0-2') + " " + labelString; + } + }; + + this.options = options; + }); + } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/storage/chargerchart.component.ts b/ui/src/app/edge/history/storage/chargerchart.component.ts index 4ad38b773b0..784c5a00eba 100644 --- a/ui/src/app/edge/history/storage/chargerchart.component.ts +++ b/ui/src/app/edge/history/storage/chargerchart.component.ts @@ -1,4 +1,3 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -6,7 +5,6 @@ import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'storageChargerChart', @@ -86,6 +84,8 @@ export class StorageChargerChartComponent extends AbstractHistoryChart implement console.error(reason); // TODO error message this.initializeChart(); return; + }).finally(async () => { + await this.setOptions(this.options); }); } @@ -99,14 +99,7 @@ export class StorageChargerChartComponent extends AbstractHistoryChart implement } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - }; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/storage/esschart.component.ts b/ui/src/app/edge/history/storage/esschart.component.ts index 9a756d7d1ae..7ee97b72963 100644 --- a/ui/src/app/edge/history/storage/esschart.component.ts +++ b/ui/src/app/edge/history/storage/esschart.component.ts @@ -1,4 +1,3 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; @@ -6,7 +5,6 @@ import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'storageESSChart', @@ -109,11 +107,12 @@ export class StorageESSChartComponent extends AbstractHistoryChart implements On } } }); + }).finally(async () => { + this.datasets = datasets; + this.loading = false; + this.stopSpinner(); + await this.setOptions(this.options); }); - this.datasets = datasets; - this.loading = false; - this.stopSpinner(); - }).catch(reason => { console.error(reason); // TODO error message this.initializeChart(); @@ -153,28 +152,7 @@ export class StorageESSChartComponent extends AbstractHistoryChart implements On } protected setLabel() { - let translate = this.translate; // enables access to TranslateService let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - // 0.005 to prevent showing Charge or Discharge if value is e.g. 0.00232138 - if (value < -0.005) { - if (label.includes(translate.instant('General.phase'))) { - label += ' ' + translate.instant('General.chargePower'); - } else { - label = translate.instant('General.chargePower'); - } - } else if (value > 0.005) { - if (label.includes(translate.instant('General.phase'))) { - label += ' ' + translate.instant('General.dischargePower'); - } else { - label = translate.instant('General.dischargePower'); - } - } - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - }; this.options = options; } diff --git a/ui/src/app/edge/history/storage/singlechart.component.ts b/ui/src/app/edge/history/storage/singlechart.component.ts index 79aba8ca000..2aa0fd4cede 100644 --- a/ui/src/app/edge/history/storage/singlechart.component.ts +++ b/ui/src/app/edge/history/storage/singlechart.component.ts @@ -2,11 +2,12 @@ import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { ChartAxis, YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; @Component({ selector: 'storageSingleChart', @@ -111,7 +112,7 @@ export class StorageSingleChartComponent extends AbstractHistoryChart implements } }); - this.getChannelAddresses(edge, config).then(channelAddresses => { + this.getChannelAddresses(edge, config).then(async channelAddresses => { channelAddresses.forEach(channelAddress => { let data = result.data[channelAddress.toString()]?.map(value => { if (value == null) { @@ -156,11 +157,8 @@ export class StorageSingleChartComponent extends AbstractHistoryChart implements } } }); + this.datasets = datasets; }); - this.datasets = datasets; - this.loading = false; - this.stopSpinner(); - }).catch(reason => { console.error(reason); // TODO error message this.initializeChart(); @@ -177,29 +175,23 @@ export class StorageSingleChartComponent extends AbstractHistoryChart implements console.error(reason); // TODO error message this.initializeChart(); return; - }); - } + }).finally(async () => { + this.unit = YAxisTitle.ENERGY; + await this.setOptions(this.options); + this.applyControllerSpecificChartOptions(this.options); + this.loading = false; + this.stopSpinner(); + });; - protected getChannelAddresses(edge: Edge, config: EdgeConfig): Promise { - return new Promise((resolve) => { - let result: ChannelAddress[] = [ - new ChannelAddress('_sum', 'EssActivePower'), - new ChannelAddress('_sum', 'ProductionDcActualPower'), - new ChannelAddress('_sum', 'EssActivePowerL1'), - new ChannelAddress('_sum', 'EssActivePowerL2'), - new ChannelAddress('_sum', 'EssActivePowerL3'), - ]; - resolve(result); - }); } - protected setLabel() { - let translate = this.translate; // enables access to TranslateService - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; + private applyControllerSpecificChartOptions(options: Chart.ChartOptions) { + const translate = this.translate; + + options.scales[ChartAxis.LEFT].min = null; + options.plugins.tooltip.callbacks.label = function (tooltipItem: Chart.TooltipItem) { + let label = tooltipItem.dataset.label; + let value = tooltipItem.dataset.data[tooltipItem.dataIndex]; // 0.005 to prevent showing Charge or Discharge if value is e.g. 0.00232138 if (value < -0.005) { if (label.includes(translate.instant('General.phase'))) { @@ -216,9 +208,31 @@ export class StorageSingleChartComponent extends AbstractHistoryChart implements } return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; }; + + // Data doesnt have all datapoints for period + // original logic has not been touched + options.scales.x.ticks['source'] = 'auto'; + this.options = options; } + protected getChannelAddresses(edge: Edge, config: EdgeConfig): Promise { + return new Promise((resolve) => { + let result: ChannelAddress[] = [ + new ChannelAddress('_sum', 'EssActivePower'), + new ChannelAddress('_sum', 'ProductionDcActualPower'), + new ChannelAddress('_sum', 'EssActivePowerL1'), + new ChannelAddress('_sum', 'EssActivePowerL2'), + new ChannelAddress('_sum', 'EssActivePowerL3'), + ]; + resolve(result); + }); + } + + protected setLabel() { + this.options = this.createDefaultChartOptions(); + } + public getChartHeight(): number { return window.innerHeight / 21 * 9; } diff --git a/ui/src/app/edge/history/storage/socchart.component.ts b/ui/src/app/edge/history/storage/socchart.component.ts index e6423f808c0..05648a9d981 100644 --- a/ui/src/app/edge/history/storage/socchart.component.ts +++ b/ui/src/app/edge/history/storage/socchart.component.ts @@ -1,12 +1,11 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from './../shared'; @Component({ selector: 'socStorageChart', @@ -57,59 +56,66 @@ export class SocStorageChartComponent extends AbstractHistoryChart implements On // convert datasets let datasets = []; let moreThanOneESS = Object.keys(result.data).length > 1 ? true : false; - this.getChannelAddresses(edge, config).then(channelAddresses => { - channelAddresses.forEach(channelAddress => { - let component = config.getComponent(channelAddress.componentId); - let data = result.data[channelAddress.toString()]?.map(value => { - if (value == null) { - return null; - } else if (value > 100 || value < 0) { - return null; + this.getChannelAddresses(edge, config) + .then(channelAddresses => { + channelAddresses.forEach(channelAddress => { + let component = config.getComponent(channelAddress.componentId); + let data = result.data[channelAddress.toString()]?.map(value => { + if (value == null) { + return null; + } else if (value > 100 || value < 0) { + return null; + } else { + return value; + } + }); + if (!data) { + return; } else { - return value; + if (channelAddress.channelId === 'EssSoc') { + datasets.push({ + label: (moreThanOneESS ? this.translate.instant('General.TOTAL') : this.translate.instant('General.soc')), + data: data, + }); + this.colors.push({ + backgroundColor: 'rgba(0,223,0,0.05)', + borderColor: 'rgba(0,223,0,1)', + }); + } + if (channelAddress.channelId === 'Soc' && moreThanOneESS) { + datasets.push({ + label: (channelAddress.componentId == component.alias ? component.id : component.alias), + data: data, + }); + this.colors.push({ + backgroundColor: 'rgba(128,128,128,0.05)', + borderColor: 'rgba(128,128,128,1)', + }); + } } - }); - if (!data) { - return; - } else { - if (channelAddress.channelId === 'EssSoc') { + if (channelAddress.channelId === 'ActualReserveSoc') { datasets.push({ - label: (moreThanOneESS ? this.translate.instant('General.TOTAL') : this.translate.instant('General.soc')), - data: data, - }); - this.colors.push({ - backgroundColor: 'rgba(0,223,0,0.05)', - borderColor: 'rgba(0,223,0,1)', - }); - } - if (channelAddress.channelId === 'Soc' && moreThanOneESS) { - datasets.push({ - label: (channelAddress.componentId == component.alias ? component.id : component.alias), + label: + this.emergencyCapacityReserveComponents.length > 1 ? component.alias : this.translate.instant("Edge.Index.EmergencyReserve.emergencyReserve"), data: data, + borderDash: [3, 3], + }); this.colors.push({ - backgroundColor: 'rgba(128,128,128,0.05)', - borderColor: 'rgba(128,128,128,1)', + backgroundColor: 'rgba(1, 1, 1,0)', + borderColor: 'rgba(1, 1, 1,1)', }); } - } - if (channelAddress.channelId === 'ActualReserveSoc') { - datasets.push({ - label: - this.emergencyCapacityReserveComponents.length > 1 ? component.alias : this.translate.instant("Edge.Index.EmergencyReserve.emergencyReserve"), - data: data, - borderDash: [3, 3], - }); - this.colors.push({ - backgroundColor: 'rgba(1, 1, 1,0)', - borderColor: 'rgba(1, 1, 1,1)', - }); - } + }); + + this.datasets = datasets; + this.loading = false; + this.stopSpinner(); + }).finally(async () => { + this.unit = YAxisTitle.PERCENTAGE; + this.formatNumber = '1.0-0'; + await this.setOptions(this.options); }); - }); - this.datasets = datasets; - this.loading = false; - this.stopSpinner(); }).catch(reason => { console.error(reason); // TODO error message @@ -154,15 +160,7 @@ export class SocStorageChartComponent extends AbstractHistoryChart implements On } protected setLabel() { - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = this.translate.instant('General.percentage'); - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; // TODO get locale dynamically - }; - options.scales.yAxes[0].ticks.max = 100; - this.options = options; + this.options = this.createDefaultChartOptions(); } public getChartHeight(): number { diff --git a/ui/src/app/edge/history/storage/totalchart.component.ts b/ui/src/app/edge/history/storage/totalchart.component.ts index 772292ad215..3a58ca7da52 100644 --- a/ui/src/app/edge/history/storage/totalchart.component.ts +++ b/ui/src/app/edge/history/storage/totalchart.component.ts @@ -1,12 +1,13 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { ChartAxis, Utils, YAxisTitle } from 'src/app/shared/service/utils'; +import { ChannelAddress, Edge, EdgeConfig, Service } from 'src/app/shared/shared'; -import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from '../../../shared/shared'; import { AbstractHistoryChart } from '../abstracthistorychart'; -import { Data, TooltipItem } from '../shared'; +import { formatNumber } from '@angular/common'; @Component({ selector: 'storageTotalChart', @@ -171,10 +172,14 @@ export class StorageTotalChartComponent extends AbstractHistoryChart implements }); } }); + }).finally(async () => { + this.datasets = datasets; + this.unit = YAxisTitle.ENERGY; + await this.setOptions(this.options); + this.applyControllerSpecificChartOptions(this.options); + this.stopSpinner(); + this.loading = false; }); - this.datasets = datasets; - this.loading = false; - this.stopSpinner(); }).catch(reason => { console.error(reason); // TODO error message @@ -230,13 +235,16 @@ export class StorageTotalChartComponent extends AbstractHistoryChart implements } protected setLabel() { - let translate = this.translate; // enables access to TranslateService - let options = this.createDefaultChartOptions(); - options.scales.yAxes[0].scaleLabel.labelString = "kW"; + this.options = this.createDefaultChartOptions(); + } + + private applyControllerSpecificChartOptions(options: Chart.ChartOptions) { + const translate = this.translate; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; + options.scales[ChartAxis.LEFT].min = null; + options.plugins.tooltip.callbacks.label = function (tooltipItem: Chart.TooltipItem) { + let label = tooltipItem.dataset.label; + let value = tooltipItem.dataset.data[tooltipItem.dataIndex]; // 0.005 to prevent showing Charge or Discharge if value is e.g. 0.00232138 if (value < -0.005) { label += ' ' + translate.instant('General.chargePower'); @@ -245,7 +253,6 @@ export class StorageTotalChartComponent extends AbstractHistoryChart implements } return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; }; - this.options = options; } public getChartHeight(): number { diff --git a/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/modal.html b/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/modal.html index e6f53513163..299cad33151 100644 --- a/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/modal.html +++ b/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/modal.html @@ -96,9 +96,8 @@ - - + + - + @@ -147,4 +145,4 @@ [info]="'Edge.Index.Widgets.GridOptimizedCharge.gridOptimizedChargeDisabled'| translate"> - \ No newline at end of file + diff --git a/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/predictionChart.ts b/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/predictionChart.ts index 91794e2725c..d639f765133 100644 --- a/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/predictionChart.ts +++ b/ui/src/app/edge/live/Controller/Ess/GridOptimizedCharge/modal/predictionChart.ts @@ -1,10 +1,11 @@ -import { formatNumber } from '@angular/common'; import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute, Data } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { AbstractHistoryChart } from 'src/app/edge/history/abstracthistorychart'; -import { ChartOptions, ChronoUnit, DEFAULT_TIME_CHART_OPTIONS, TooltipItem } from 'src/app/edge/history/shared'; +import { ChronoUnit, DEFAULT_TIME_CHART_OPTIONS } from 'src/app/edge/history/shared'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; +import { ChartAxis, YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from 'src/app/shared/shared'; @Component({ @@ -49,7 +50,7 @@ export class PredictionChartComponent extends AbstractHistoryChart implements On this.loading = true; this.colors = []; - this.queryHistoricTimeseriesData(PredictionChartComponent.DEFAULT_PERIOD.from, PredictionChartComponent.DEFAULT_PERIOD.to, { unit: ChronoUnit.Type.MINUTES, value: 5 }).then(response => { + this.queryHistoricTimeseriesData(PredictionChartComponent.DEFAULT_PERIOD.from, PredictionChartComponent.DEFAULT_PERIOD.to, { unit: ChronoUnit.Type.MINUTES, value: 5 }).then(async response => { let result = response.result; let datasets = []; @@ -172,14 +173,12 @@ export class PredictionChartComponent extends AbstractHistoryChart implements On label: this.translate.instant('General.soc'), data: socData, hidden: false, - yAxisID: 'yAxis2', - position: 'right', + yAxisID: ChartAxis.RIGHT, }, { label: this.translate.instant('Edge.Index.Widgets.GridOptimizedCharge.expectedSoc'), data: predictedSocData, hidden: false, - yAxisID: 'yAxis2', - position: 'right', + yAxisID: ChartAxis.RIGHT, }); // Push the depending colors @@ -195,6 +194,10 @@ export class PredictionChartComponent extends AbstractHistoryChart implements On this.datasets = datasets; this.loading = false; this.service.stopSpinner(this.spinnerId); + this.unit = YAxisTitle.PERCENTAGE; + this.formatNumber = '1.0-0'; + await this.setOptions(this.options); + this.applyControllerSpecificOptions(); }).catch(reason => { console.error(reason); // TODO error message @@ -203,6 +206,16 @@ export class PredictionChartComponent extends AbstractHistoryChart implements On }); } + private applyControllerSpecificOptions() { + this.options.scales[ChartAxis.LEFT]['position'] = 'right'; + this.options.scales.x.ticks.callback = function (value, index, values) { + var date = new Date(value); + + // Display the label only if the minutes are zero (full hour) + return date.getMinutes() === 0 ? date.getHours() + ':00' : ''; + }; + } + protected getChannelAddresses(): Promise { return new Promise((resolve) => { @@ -221,58 +234,8 @@ export class PredictionChartComponent extends AbstractHistoryChart implements On } protected setLabel() { - let translate = this.translate; - let options = Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS); - - // Remove left y axis for now - options.scales.yAxes.shift(); - - // adds second y-axis to chart - options.scales.yAxes - .push({ - id: 'yAxis2', - position: 'right', - scaleLabel: { - display: true, - labelString: "%", - padding: -2, - fontSize: 11, - }, - gridLines: { - display: true, - }, - ticks: { - beginAtZero: true, - max: 100, - padding: -5, - stepSize: 20, - }, - }); - - options.layout = { - padding: { - left: 2, - right: 2, - top: 0, - bottom: 0, - }, - }; - //x-axis - options.scales.xAxes[0].time.unit = "hour"; - - //y-axis - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.yLabel; - if (label == translate.instant('General.soc') || label == translate.instant('Edge.Index.Widgets.GridOptimizedCharge.expectedSoc')) { - return label + ": " + formatNumber(value, 'de', '1.0-0') + " %"; - } else { - return label + ": " + formatNumber(value, 'de', '1.0-2') + " kW"; - } - }; - this.options = options; + this.options = Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS); } - } export type ChannelChartDescription = { diff --git a/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/modal.html b/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/modal.html index 9e68a6f896c..7fffeb3ac01 100644 --- a/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/modal.html +++ b/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/modal.html @@ -61,7 +61,5 @@ [innerHtml]="'Edge.Index.Widgets.TIME_OF_USE_TARIFF.CONTROL_MODE_DESCRIPTION.CHARGE_CONSUMPTION' | translate"> - - diff --git a/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/powerSocChart.ts b/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/powerSocChart.ts index beaa7b6d1aa..a74da363843 100644 --- a/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/powerSocChart.ts +++ b/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/powerSocChart.ts @@ -1,11 +1,14 @@ import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute, Data } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { AbstractHistoryChart } from 'src/app/edge/history/abstracthistorychart'; -import { ChartOptions, DEFAULT_TIME_CHART_OPTIONS, TooltipItem } from 'src/app/edge/history/shared'; +import { DEFAULT_TIME_CHART_OPTIONS } from 'src/app/edge/history/shared'; +import { AbstractHistoryChart as NewAbstractHistoryChart } from 'src/app/shared/genericComponents/chart/abstracthistorychart'; import { ComponentJsonApiRequest } from 'src/app/shared/jsonrpc/request/componentJsonApiRequest'; -import { HistoryUtils, TimeOfUseTariffUtils } from 'src/app/shared/service/utils'; +import { ChartAxis, HistoryUtils, TimeOfUseTariffUtils, YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Edge, EdgeConfig, Service, Utils, Websocket } from 'src/app/shared/shared'; + import { GetScheduleRequest } from '../../../../../../shared/jsonrpc/request/getScheduleRequest'; import { GetScheduleResponse } from '../../../../../../shared/jsonrpc/response/getScheduleResponse'; @@ -156,17 +159,16 @@ export class SchedulePowerAndSocChartComponent extends AbstractHistoryChart impl label: this.translate.instant('General.soc'), data: socArray, hidden: false, - yAxisID: 'yAxis2', - position: 'right', + yAxisID: ChartAxis.RIGHT, borderDash: [10, 10], order: 1, + unit: YAxisTitle.PERCENTAGE, }); this.colors.push({ backgroundColor: 'rgba(189, 195, 199,0.2)', borderColor: 'rgba(189, 195, 199,1)', }); - this.datasets = datasets; this.loading = false; this.labels = labels; @@ -176,55 +178,45 @@ export class SchedulePowerAndSocChartComponent extends AbstractHistoryChart impl console.error(reason); this.initializeChart(); return; + }).finally(async () => { + this.unit = YAxisTitle.POWER; + await this.setOptions(this.options); + this.applyControllerSpecificOptions(); }); } - protected setLabel() { - const options = Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS); - const translate = this.translate; + private applyControllerSpecificOptions() { + const rightYAxis: HistoryUtils.yAxes = { position: 'right', unit: YAxisTitle.PERCENTAGE, yAxisId: ChartAxis.RIGHT }; + const locale = this.service.translate.currentLang; + this.options = NewAbstractHistoryChart.getYAxisOptions(this.options, rightYAxis, this.translate, 'line', locale); + + this.datasets = this.datasets.map((el, index, arr) => { - //x-axis - options.scales.xAxes[0].time.unit = "hour"; - - //y-axis - options.scales.yAxes[0].id = "yAxis1"; - options.scales.yAxes[0].scaleLabel.padding = -2; - options.scales.yAxes[0].scaleLabel.fontSize = 11; - options.scales.yAxes[0].ticks.padding = -5; - options.scales.yAxes[0].ticks.beginAtZero = false; // scale with min and max values. - - // Adds second y-axis to chart - options.scales.yAxes.push({ - id: 'yAxis2', - position: 'right', - scaleLabel: { - display: true, - labelString: "%", - padding: -2, - fontSize: 11, - }, - gridLines: { - display: false, - }, - ticks: { - beginAtZero: true, - max: 100, - padding: -5, - stepSize: 20, - }, + // align last element to right yAxis + if ((arr.length - 1) === index) { + el['yAxisID'] = ChartAxis.RIGHT; + el['yAxisId'] = ChartAxis.RIGHT; + } + return el; }); - options.layout = { - padding: { - left: 2, - right: 2, - top: 0, - bottom: 0, - }, + this.options.scales.x['ticks'] = { source: 'auto', autoSkip: false }; + this.options.scales.x.ticks.callback = function (value, index, values) { + var date = new Date(value); + + // Display the label only if the minutes are zero (full hour) + return date.getMinutes() === 0 ? date.getHours() + ':00' : ''; }; - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - const label: string = data.datasets[tooltipItem.datasetIndex].label; - const value: number = tooltipItem.yLabel; + this.options.scales[ChartAxis.RIGHT].grid.display = false; + }; + + protected setLabel() { + const options = Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS); + const translate = this.translate; + options.plugins.tooltip.callbacks.label = function (item: Chart.TooltipItem) { + + const label = item.dataset.label; + const value = item.dataset.data[item.dataIndex]; return TimeOfUseTariffUtils.getLabel(value, label, translate); }; diff --git a/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/statePriceChart.ts b/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/statePriceChart.ts index de1576a0c10..731f882af59 100644 --- a/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/statePriceChart.ts +++ b/ui/src/app/edge/live/Controller/Ess/TimeOfUseTariff/modal/statePriceChart.ts @@ -1,11 +1,14 @@ import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; -import { ActivatedRoute, Data } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; +import * as Chart from 'chart.js'; import { AbstractHistoryChart } from 'src/app/edge/history/abstracthistorychart'; -import { TooltipItem } from 'src/app/edge/history/shared'; import { ComponentJsonApiRequest } from 'src/app/shared/jsonrpc/request/componentJsonApiRequest'; -import { TimeOfUseTariffUtils } from 'src/app/shared/service/utils'; +import { ChartAxis, TimeOfUseTariffUtils, YAxisTitle } from 'src/app/shared/service/utils'; import { ChannelAddress, Currency, Edge, EdgeConfig, Service, Websocket } from 'src/app/shared/shared'; + +import { calculateResolution } from 'src/app/edge/history/shared'; +import { ColorUtils } from 'src/app/shared/utils/color/color.utils'; import { GetScheduleRequest } from '../../../../../../shared/jsonrpc/request/getScheduleRequest'; import { GetScheduleResponse } from '../../../../../../shared/jsonrpc/response/getScheduleResponse'; @@ -78,32 +81,61 @@ export class ScheduleStateAndPriceChartComponent extends AbstractHistoryChart im console.error(reason); this.initializeChart(); return; + }).finally(async () => { + this.unit = YAxisTitle.CURRENCY; + await this.setOptions(this.options); + this.applyControllerSpecificOptions(this.options); }); } - protected setLabel() { - const options = this.createDefaultChartOptions(); - const translate = this.translate; - const currencyLabel: Currency.Label = this.currencyLabel; - - //x-axis - options.scales.xAxes[0].time.unit = "hour"; - options.scales.xAxes[0].stacked = true; - - //y-axis - options.scales.yAxes[0].id = "yAxis1"; - options.scales.yAxes[0].scaleLabel.padding = -2; - options.scales.yAxes[0].scaleLabel.fontSize = 11; - options.scales.yAxes[0].ticks.padding = -5; - options.scales.yAxes[0].ticks.beginAtZero = false; // scale with min and max values. - - options.tooltips.callbacks.label = function (tooltipItem: TooltipItem, data: Data) { - const label: string = data.datasets[tooltipItem.datasetIndex].label; - const value: number = tooltipItem.yLabel; - - return TimeOfUseTariffUtils.getLabel(value, label, translate, currencyLabel); + private applyControllerSpecificOptions(options: Chart.ChartOptions) { + + options.scales.x['time'].unit = calculateResolution(this.service, this.service.historyPeriod.value.from, this.service.historyPeriod.value.to).timeFormat; + options.scales.x['ticks'] = { source: 'auto', autoSkip: false }; + options.scales.x.ticks.maxTicksLimit = 18; + options.scales.x['offset'] = false; + options.scales.x.ticks.callback = function (value, index, values) { + var date = new Date(value); + + // Display the label only if the minutes are zero (full hour) + return date.getMinutes() === 0 ? date.getHours() + ':00' : ''; + }; + + // options.plugins. + options.plugins.tooltip.mode = 'index'; + options.plugins.tooltip.callbacks.labelColor = (item: Chart.TooltipItem) => { + if (!item) { + return; + } + return { + borderColor: ColorUtils.changeOpacityFromRGBA(item.dataset.borderColor, 1), + backgroundColor: item.dataset.backgroundColor, + }; + }; + + this.datasets = this.datasets.map((el) => { + let opacity = el.type === 'line' ? 0.2 : 0.5; + + if (el.backgroundColor && el.borderColor) { + el.backgroundColor = ColorUtils.changeOpacityFromRGBA(el.backgroundColor.toString(), opacity); + el.borderColor = ColorUtils.changeOpacityFromRGBA(el.borderColor.toString(), 1); + } + return el; + }); + + options.plugins.tooltip.callbacks.label = (item: Chart.TooltipItem) => { + + const label = item.dataset.label; + const value = item.dataset.data[item.dataIndex]; + + return TimeOfUseTariffUtils.getLabel(value, label, this.translate, this.currencyLabel); }; - this.options = options; + + options.scales[ChartAxis.LEFT]['title'].display = false; + } + + protected setLabel() { + this.options = this.createDefaultChartOptions(); } protected getChannelAddresses(): Promise { diff --git a/ui/src/app/edge/live/Multiple/Evcs_Api_Cluster/modal/evcs-chart/evcs.chart.ts b/ui/src/app/edge/live/Multiple/Evcs_Api_Cluster/modal/evcs-chart/evcs.chart.ts index 1ab4f51fd97..43997648b4b 100644 --- a/ui/src/app/edge/live/Multiple/Evcs_Api_Cluster/modal/evcs-chart/evcs.chart.ts +++ b/ui/src/app/edge/live/Multiple/Evcs_Api_Cluster/modal/evcs-chart/evcs.chart.ts @@ -1,12 +1,10 @@ -import { ChartDataSets } from 'chart.js'; +import * as Chart from 'chart.js'; import { Component, Input, OnInit, OnChanges } from '@angular/core'; import { CurrentData } from 'src/app/shared/edge/currentdata'; import { Data } from 'src/app/edge/history/shared'; import { EdgeConfig, Edge } from 'src/app/shared/shared'; -import { Label } from 'ng2-charts'; import { ModalController } from '@ionic/angular'; import { TranslateService } from '@ngx-translate/core'; -import * as Chart from 'chart.js'; @Component({ selector: EvcsChartComponent.SELECTOR, @@ -23,9 +21,9 @@ export class EvcsChartComponent implements OnInit, OnChanges { private static readonly SELECTOR = "evcsChart"; public loading: boolean = true; public options: BarChartOptions; - public labels: Label[]; - public datasets: ChartDataSets[]; - public chart: Chart; // This will hold our chart info + public labels: any[]; + public datasets: Chart.ChartDataset[]; + public chart: Chart.Chart; // This will hold our chart info constructor( diff --git a/ui/src/app/shared/edge/edgeconfig.spec.ts b/ui/src/app/shared/edge/edgeconfig.spec.ts index 3d885c512e8..b918850761d 100644 --- a/ui/src/app/shared/edge/edgeconfig.spec.ts +++ b/ui/src/app/shared/edge/edgeconfig.spec.ts @@ -1,4 +1,6 @@ +import { TimeUnit } from "chart.js"; import { SumState } from "src/app/index/shared/sumState"; + import { TextIndentation } from "../genericComponents/modal/modal-line/modal-line"; import { OeChartTester, OeFormlyViewTester } from "../genericComponents/shared/testing/tester"; import { Role } from "../type/role"; @@ -281,6 +283,17 @@ export const LINE_INFO = (text: string): OeFormlyViewTester.Field => ({ }); export namespace ChartConfig { - export const LINE_CHART_OPTIONS = (period: string, labelString?: string): OeChartTester.Dataset.Option => ({ type: 'option', options: { "maintainAspectRatio": false, "legend": { "labels": {}, "position": "bottom" }, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "borderWidth": 2, "tension": 0.1 }, "rectangle": { "borderWidth": 2 } }, "hover": { "mode": "point", "intersect": true }, "scales": { "yAxes": [{ "id": "left", "position": "left", "scaleLabel": { "display": true, "labelString": labelString ?? "kW", "padding": 5, "fontSize": 11 }, "gridLines": { "display": true }, "ticks": { "beginAtZero": false } }], "xAxes": [{ "ticks": {}, "stacked": false, "type": "time", "time": { "minUnit": "hour", "displayFormats": { "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:[00]", "day": "DD", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "YYYY" }, "unit": period }, "bounds": "ticks" }] }, "tooltips": { "mode": "index", "intersect": false, "axis": "x", "callbacks": {} }, "responsive": true } }); - export const BAR_CHART_OPTIONS = (period: string, labelString?: string): OeChartTester.Dataset.Option => ({ type: 'option', options: { "maintainAspectRatio": false, "legend": { "labels": {}, "position": "bottom" }, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "borderWidth": 2, "tension": 0.1 }, "rectangle": { "borderWidth": 2 } }, "hover": { "mode": "point", "intersect": true }, "scales": { "yAxes": [{ "id": "left", "position": "left", "scaleLabel": { "display": true, "labelString": labelString ?? "kWh", "padding": 5, "fontSize": 11 }, "gridLines": { "display": true }, "ticks": { "beginAtZero": false }, "stacked": true }], "xAxes": [{ "ticks": { "maxTicksLimit": 12, "source": "data" }, "stacked": true, "type": "time", "time": { "minUnit": "hour", "displayFormats": { "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:[00]", "day": "DD", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "YYYY" }, "unit": period }, "offset": true, "bounds": "ticks" }] }, "tooltips": { "mode": "x", "intersect": false, "axis": "x", "callbacks": {} }, "responsive": true } }); + + export const LINE_CHART_OPTIONS = (period: string, chartType: 'line' | 'bar', labelString?: string): OeChartTester.Dataset.Option => ({ + type: 'option', + options: { "responsive": true, "maintainAspectRatio": false, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "stepped": false, "fill": true } }, "datasets": { "bar": {}, "line": {} }, "plugins": { "colors": { "enabled": false }, "legend": { "display": true, "position": "bottom", "labels": { "color": '' } }, "tooltip": { "intersect": false, "mode": "index", "callbacks": {} } }, "scales": { "x": { "stacked": true, "offset": false, "type": "time", "ticks": { "source": "auto", "maxTicksLimit": 31 }, "bounds": "ticks", "adapters": { "date": { "locale": { "code": "de", "formatLong": {}, "localize": {}, "match": {}, "options": { "weekStartsOn": 1, "firstWeekContainsDate": 4 } } } }, "time": { "unit": period as TimeUnit, "displayFormats": { "datetime": "yyyy-MM-dd HH:mm:ss", "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:00", "day": "dd", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "yyyy" } } }, "left": { ...(chartType === 'line' ? { stacked: false } : {}), "title": { "text": "kW", "display": true, "padding": 5, "font": { "size": 11 } }, "position": "left", "grid": { "display": true }, "ticks": {} } } }, + }); + + export const BAR_CHART_OPTIONS = (period: string, chartType: 'line' | 'bar', labelString?: string): OeChartTester.Dataset.Option => ({ + type: 'option', options: { + "responsive": true, "maintainAspectRatio": false, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "stepped": false, "fill": true } }, "datasets": { "bar": { "barPercentage": 1 }, "line": {} }, "plugins": { "colors": { "enabled": false }, "legend": { "display": true, "position": "bottom", "labels": { "color": '' } }, "tooltip": { "intersect": false, "mode": "x", "callbacks": {} } }, "scales": { + "x": { "stacked": true, "offset": true, "type": "time", "ticks": { "source": "auto", "maxTicksLimit": 31 }, "bounds": "ticks", "adapters": { "date": { "locale": { "code": "de", "formatLong": {}, "localize": {}, "match": {}, "options": { "weekStartsOn": 1, "firstWeekContainsDate": 4 } } } }, "time": { "unit": period as TimeUnit, "displayFormats": { "datetime": "yyyy-MM-dd HH:mm:ss", "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:00", "day": "dd", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "yyyy" } } }, "left": { ...(chartType === 'line' ? { stacked: false } : {}), "title": { "text": "kWh", "display": true, "padding": 5, "font": { "size": 11 } }, "position": "left", "grid": { "display": true }, "ticks": {} }, + }, + }, + }); } diff --git a/ui/src/app/shared/formly/input.html b/ui/src/app/shared/formly/input.html index a9de42b1c57..abc8b4b0ea0 100644 --- a/ui/src/app/shared/formly/input.html +++ b/ui/src/app/shared/formly/input.html @@ -1,10 +1,10 @@ + style="width:100%; float:right; text-align: right" + [type]="props.type || 'text'" [formControl]="formControl" + [min]="props.min"> - \ No newline at end of file + diff --git a/ui/src/app/shared/genericComponents/chart/abstracthistorychart.html b/ui/src/app/shared/genericComponents/chart/abstracthistorychart.html index 1e3040ac518..e0ac9bd56e9 100644 --- a/ui/src/app/shared/genericComponents/chart/abstracthistorychart.html +++ b/ui/src/app/shared/genericComponents/chart/abstracthistorychart.html @@ -7,7 +7,6 @@
- +
\ No newline at end of file diff --git a/ui/src/app/shared/genericComponents/chart/abstracthistorychart.ts b/ui/src/app/shared/genericComponents/chart/abstracthistorychart.ts index e6beba8f891..d4305108ae7 100644 --- a/ui/src/app/shared/genericComponents/chart/abstracthistorychart.ts +++ b/ui/src/app/shared/genericComponents/chart/abstracthistorychart.ts @@ -1,14 +1,12 @@ import { DecimalPipe, formatNumber } from '@angular/common'; import { ChangeDetectorRef, Directive, Input, OnInit } from '@angular/core'; -import { ActivatedRoute, Data } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import * as Chart from 'chart.js'; -import { ChartDataSets, ChartLegendLabelItem, ChartTooltipItem } from 'chart.js'; import { QueryHistoricTimeseriesEnergyPerPeriodResponse } from 'src/app/shared/jsonrpc/response/queryHistoricTimeseriesEnergyPerPeriodResponse'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; -import { v4 as uuidv4 } from 'uuid'; - -import { calculateResolution, ChartOptions, ChronoUnit, DEFAULT_TIME_CHART_OPTIONS, DEFAULT_TIME_CHART_OPTIONS_WITHOUT_PREDEFINED_Y_AXIS, isLabelVisible, Resolution, setLabelVisible, TooltipItem } from '../../../edge/history/shared'; +import 'chartjs-adapter-date-fns'; +import { DEFAULT_TIME_CHART_OPTIONS, isLabelVisible, calculateResolution, ChronoUnit, Resolution, setLabelVisible } from 'src/app/edge/history/shared'; import { JsonrpcResponseError } from '../../jsonrpc/base'; import { QueryHistoricTimeseriesDataRequest } from '../../jsonrpc/request/queryHistoricTimeseriesDataRequest'; import { QueryHistoricTimeseriesEnergyPerPeriodRequest } from '../../jsonrpc/request/queryHistoricTimeseriesEnergyPerPeriodRequest'; @@ -16,15 +14,18 @@ import { QueryHistoricTimeseriesEnergyRequest } from '../../jsonrpc/request/quer import { QueryHistoricTimeseriesDataResponse } from '../../jsonrpc/response/queryHistoricTimeseriesDataResponse'; import { QueryHistoricTimeseriesEnergyResponse } from '../../jsonrpc/response/queryHistoricTimeseriesEnergyResponse'; import { FormatSecondsToDurationPipe } from '../../pipe/formatSecondsToDuration/formatSecondsToDuration.pipe'; -import { ChartAxis, HistoryUtils, YAxisTitle } from '../../service/utils'; -import { ChannelAddress, Edge, EdgeConfig, Service, Utils } from "../../shared"; +import { HistoryUtils, ChartAxis, YAxisTitle } from '../../service/utils'; +import { EdgeConfig, Edge, Service, Utils, ChannelAddress, Currency } from '../../shared'; import { Language } from '../../type/language'; +import { ColorUtils } from '../../utils/color/color.utils'; import { DateUtils } from '../../utils/date/dateutils'; import { DateTimeUtils } from '../../utils/datetime/datetime-utils'; import { TimeUtils } from '../../utils/time/timeutils'; import { Converter } from '../shared/converter'; +import { v4 as uuidv4 } from 'uuid'; // NOTE: Auto-refresh of widgets is currently disabled to reduce server load + @Directive() export abstract class AbstractHistoryChart implements OnInit { @@ -40,10 +41,10 @@ export abstract class AbstractHistoryChart implements OnInit { public edge: Edge | null = null; public loading: boolean = true; public labels: Date[] = []; - public datasets: ChartDataSets[] = HistoryUtils.createEmptyDataset(this.translate); - public options: ChartOptions | null = DEFAULT_TIME_CHART_OPTIONS; + public datasets: Chart.ChartDataset[] = HistoryUtils.createEmptyDataset(this.translate); + public options: Chart.ChartOptions | null = DEFAULT_TIME_CHART_OPTIONS; public colors: any[] = []; - public chartObject: HistoryUtils.ChartData = null; + public chartObject: HistoryUtils.ChartData | null = null; protected spinnerId: string = uuidv4(); protected chartType: 'line' | 'bar' = 'line'; @@ -142,8 +143,7 @@ export abstract class AbstractHistoryChart implements OnInit { }); // Fill datasets, labels and colors - let datasets: ChartDataSets[] = []; - let colors: any[] = []; + let datasets: Chart.ChartDataset[] = []; let displayValues: HistoryUtils.DisplayValues[] = chartObject.output(channelData.data); let legendOptions: { label: string, strokeThroughHidingStyle: boolean, hideLabelInLegend: boolean }[] = []; displayValues.forEach((element, index) => { @@ -168,40 +168,34 @@ export abstract class AbstractHistoryChart implements OnInit { let configuration = AbstractHistoryChart.fillData(element, label, chartObject, chartType, data); datasets.push(...configuration.datasets); legendOptions.push(...configuration.legendOptions); - colors.push(...configuration.colors); } }); return { datasets: datasets, - colors: colors, labels: labels, legendOptions: legendOptions, }; } - public static fillData(element: HistoryUtils.DisplayValues, label: string, chartObject: HistoryUtils.ChartData, chartType: 'line' | 'bar', data: number[] | null): { datasets: ChartDataSets[], colors: any[], legendOptions: { label: string, strokeThroughHidingStyle: boolean, hideLabelInLegend: boolean }[] } { + public static fillData(element: HistoryUtils.DisplayValues, label: string, chartObject: HistoryUtils.ChartData, chartType: 'line' | 'bar', data: number[] | null): { datasets: Chart.ChartDataset[], legendOptions: { label: string, strokeThroughHidingStyle: boolean, hideLabelInLegend: boolean }[] } { let legendOptions: { label: string, strokeThroughHidingStyle: boolean, hideLabelInLegend: boolean }[] = []; - let datasets: ChartDataSets[] = []; - let colors: any[] = []; - + let datasets: Chart.ChartDataset[] = []; + // Enable one dataset to be displayed in multiple stacks if (Array.isArray(element.stack)) { for (let stack of element.stack) { - datasets.push(AbstractHistoryChart.getDataSet(element, label, data, stack, chartObject, element.customType)); - colors.push(AbstractHistoryChart.getColors(element.color, chartType)); + datasets.push(AbstractHistoryChart.getDataSet(element, label, data, stack, chartObject, element.custom?.type ?? chartType)); legendOptions.push(AbstractHistoryChart.getLegendOptions(label, element)); } } else { - datasets.push(AbstractHistoryChart.getDataSet(element, label, data, element.stack, chartObject, element.customType)); - colors.push(AbstractHistoryChart.getColors(element.color, chartType)); + datasets.push(AbstractHistoryChart.getDataSet(element, label, data, element.stack, chartObject, element.custom?.type ?? chartType)); legendOptions.push(AbstractHistoryChart.getLegendOptions(label, element)); } return { datasets: datasets, - colors: colors, legendOptions: legendOptions, }; } @@ -244,9 +238,8 @@ export abstract class AbstractHistoryChart implements OnInit { * @param stack the stack * @returns a dataset */ - public static getDataSet(element: HistoryUtils.DisplayValues, label: string, data: number[], stack: number, chartObject: HistoryUtils.ChartData, chartType: ChartType): Chart.ChartDataSets { - let dataset: Chart.ChartDataSets; - + public static getDataSet(element: HistoryUtils.DisplayValues, label: string, data: number[], stack: number, chartObject: HistoryUtils.ChartData, chartType: 'line' | 'bar'): Chart.ChartDataset { + let dataset: Chart.ChartDataset; dataset = { label: label, data: data, @@ -257,7 +250,9 @@ export abstract class AbstractHistoryChart implements OnInit { yAxisID: element.yAxisId != null ? element.yAxisId : chartObject.yAxes.find(element => element.yAxisId == ChartAxis.LEFT)?.yAxisId, order: element.order ?? Number.MAX_VALUE, ...(element.hideShadow && { fill: !element.hideShadow }), - ...(element.customType && { type: chartType }), + ...(element.custom?.type && { type: chartType }), + ...AbstractHistoryChart.getColors(element.color, chartType), + borderWidth: 2, }; return dataset; } @@ -284,46 +279,9 @@ export abstract class AbstractHistoryChart implements OnInit { let displayValues = AbstractHistoryChart.fillChart(this.chartType, this.chartObject, energyPeriodResponse, energyResponse); this.datasets = displayValues.datasets; - this.colors = displayValues.colors; this.legendOptions = displayValues.legendOptions; this.labels = displayValues.labels; this.setChartLabel(); - }).finally(() => { - - let barWidthPercentage = 0; - let categoryGapPercentage = 0; - switch (this.service.periodString) { - case DefaultTypes.PeriodString.CUSTOM: { - barWidthPercentage = 0.7; - categoryGapPercentage = 0.4; - break; - } - case DefaultTypes.PeriodString.MONTH: { - if (this.service.isSmartphoneResolution == true) { - barWidthPercentage = 1; - categoryGapPercentage = 0.6; - } else { - barWidthPercentage = 0.9; - categoryGapPercentage = 0.8; - } - break; - } - case DefaultTypes.PeriodString.YEAR: - case DefaultTypes.PeriodString.TOTAL: { - if (this.service.isSmartphoneResolution == true) { - barWidthPercentage = 1; - categoryGapPercentage = 0.6; - } else { - barWidthPercentage = 0.8; - categoryGapPercentage = 0.8; - } - break; - } - } - this.datasets.forEach(element => { - element.barPercentage = barWidthPercentage; - element.categoryPercentage = categoryGapPercentage; - }); }); } else { @@ -339,7 +297,6 @@ export abstract class AbstractHistoryChart implements OnInit { this.chartObject = this.getChartData(); let displayValues = AbstractHistoryChart.fillChart(this.chartType, this.chartObject, dataResponse, energyResponse); this.datasets = displayValues.datasets; - this.colors = displayValues.colors; this.legendOptions = displayValues.legendOptions; this.labels = displayValues.labels; this.setChartLabel(); @@ -347,6 +304,66 @@ export abstract class AbstractHistoryChart implements OnInit { } } + /** + * Change ChartOptions dependent on chartType + * + * @param chartType the chart type + * @returns chart options + */ + public static applyChartTypeSpecificOptionsChanges(chartType: string, options: Chart.ChartOptions, service: Service, chartObject: HistoryUtils.ChartData | null): Chart.ChartOptions { + switch (chartType) { + case 'bar': + options.plugins.tooltip.mode = 'x'; + options.scales.x['offset'] = true; + options.scales.x.ticks['source'] = 'data'; + let barPercentage = 1; + let categoryPercentage = 0; + switch (service.periodString) { + case DefaultTypes.PeriodString.CUSTOM: { + barPercentage = 0.7; + categoryPercentage = 0.4; + } + case DefaultTypes.PeriodString.MONTH: { + if (service.isSmartphoneResolution == true) { + barPercentage = 1; + categoryPercentage = 0.6; + } else { + barPercentage = 0.9; + categoryPercentage = 0.8; + } + } + case DefaultTypes.PeriodString.YEAR: { + if (service.isSmartphoneResolution == true) { + barPercentage = 1; + categoryPercentage = 0.6; + } else { + barPercentage = 0.8; + categoryPercentage = 0.8; + } + } + } + + options.datasets.bar = { + barPercentage: barPercentage, + }; + break; + + case 'line': + options.scales.x['offset'] = false; + options.scales.x.ticks['source'] = 'data'; + options.plugins.tooltip.mode = 'index'; + + if (chartObject) { + for (let yAxis of chartObject.yAxes) { + options.scales[yAxis.yAxisId]['stacked'] = false; + } + } + break; + } + + return options; + } + /** * Sends the Historic Timeseries Data Query and makes sure the result is not empty. * @@ -514,192 +531,46 @@ export abstract class AbstractHistoryChart implements OnInit { } } + /** + * Gets chart options {@link Chart.ChartOptions} + * + * @param chartObject the chartObject + * @param chartType the current chart type + * @param service the service + * @param translate the translate service + * @param legendOptions the legend options + * @param channelData the channel data + * @param locale the locale + * @returns options + */ public static getOptions(chartObject: HistoryUtils.ChartData, chartType: 'line' | 'bar', service: Service, - translate: TranslateService, legendOptions: { label: string, strokeThroughHidingStyle: boolean }[], channelData: { data: { [name: string]: number[] } }, locale: string): ChartOptions { + translate: TranslateService, legendOptions: { label: string, strokeThroughHidingStyle: boolean }[], channelData: { data: { [name: string]: number[] } }, locale: string, config: EdgeConfig): Chart.ChartOptions { let tooltipsLabel: string | null = null; - let options = Utils.deepCopy(Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS_WITHOUT_PREDEFINED_Y_AXIS)); - chartObject.yAxes.forEach((element) => { - switch (element.unit) { + let options: Chart.ChartOptions = Utils.deepCopy(Utils.deepCopy(DEFAULT_TIME_CHART_OPTIONS)); - case YAxisTitle.RELAY: - - if (chartType === ChartType.LINE) { - - options.scales.yAxes.push({ - id: element.yAxisId, - position: element.position, - scaleLabel: { - display: true, - labelString: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), - padding: 10, - }, - gridLines: { - display: element.displayGrid ?? true, - }, - ticks: { - - // Two states are possible - callback: function (value, index, ticks) { - return Converter.ON_OFF(translate)(value); - }, - min: 0, - max: 1, - beginAtZero: true, - padding: 5, - stepSize: 20, - }, - }); - } - - if (chartType === ChartType.BAR) { - options.scales.yAxes.push({ - id: element.yAxisId, - position: element.position, - scaleLabel: { - display: true, - labelString: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), - padding: 5, - fontSize: 11, - }, - gridLines: { - display: element.displayGrid ?? true, - }, - ticks: { - min: 0, - beginAtZero: true, - callback: function (value, index, values) { - return TimeUtils.formatSecondsToDuration(value, locale); - }, - }, - }); - } - break; - - case YAxisTitle.PERCENTAGE: - options.scales.yAxes.push({ - id: element.yAxisId, - position: element.position, - scaleLabel: { - display: true, - labelString: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), - padding: 10, - }, - gridLines: { - display: element.displayGrid ?? true, - }, - ticks: { - beginAtZero: true, - max: 100, - padding: 5, - stepSize: 20, - }, - }); - break; - - case YAxisTitle.TIME: - options.scales.yAxes.push({ - id: element.yAxisId, - position: element.position, - scaleLabel: { - display: true, - labelString: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), - padding: 5, - fontSize: 11, - }, - gridLines: { - display: element.displayGrid ?? true, - }, - ticks: { - min: 0, - beginAtZero: true, - callback: function (value, index, values) { - return TimeUtils.formatSecondsToDuration(value, locale); - }, - }, - }); - break; - case YAxisTitle.ENERGY: - case YAxisTitle.VOLTAGE: - options.scales.yAxes.push({ - id: element.yAxisId, - position: element.position, - scaleLabel: { - display: true, - labelString: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), - padding: 5, - fontSize: 11, - }, - gridLines: { - display: element.displayGrid ?? true, - }, - ticks: { - beginAtZero: false, - }, - }); - break; - } + chartObject.yAxes.forEach((element) => { + options = AbstractHistoryChart.getYAxisOptions(options, element, translate, chartType, locale); }); - options.scales.xAxes[0].time.unit = calculateResolution(service, service.historyPeriod.value.from, service.historyPeriod.value.to).timeFormat; - - if (chartType == 'bar') { - options.scales.xAxes[0].stacked = true; - options.scales.yAxes[0].stacked = true; - options.scales.xAxes[0].offset = true; - options.scales.xAxes[0].ticks.maxTicksLimit = 12; - options.scales.xAxes[0].ticks.source = 'data'; - - // Enables tooltip for each datasetindex / stack - options.tooltips.mode = 'x'; - - - // Second line in tooltip - options.tooltips.callbacks.afterTitle = function (items: ChartTooltipItem[], data: Data) { - - // only way to figure out, which stack is active - var tooltipItem = items[0]; // Assuming only one tooltip item is displayed - var datasetIndex = tooltipItem.datasetIndex; - // Get the dataset object - var dataset = data.datasets[datasetIndex]; - - // Assuming the dataset is a bar chart using the 'stacked' option - var stack = dataset.stack || datasetIndex; - - // If only one item in stack do not show sum of values - if (items.length <= 1) { - return null; - } - - let afterTitle = typeof chartObject.tooltip?.afterTitle == 'function' ? chartObject.tooltip?.afterTitle(stack) : null; - let totalValue = items.filter(element => !element.label.includes(afterTitle, - )).reduce((a, e) => a + parseFloat(e.yLabel), 0); - - if (afterTitle) { - return afterTitle + ": " + formatNumber(totalValue, 'de', chartObject.tooltip.formatNumber) + ' ' + tooltipsLabel ?? AbstractHistoryChart.getToolTipsAfterTitleLabel(YAxisTitle.ENERGY, chartType, totalValue, translate); - } - + options.plugins.tooltip.callbacks.title = (tooltipItems: Chart.TooltipItem[]): string => { + if (tooltipItems?.length === 0) { return null; - }; - } - - options.scales.xAxes[0].bounds = 'ticks'; - options.responsive = true; - - // Overwrite Tooltips -Title -Label - options.tooltips.callbacks.title = (tooltipItems: TooltipItem[], data: Data): string => { - let date = new Date(tooltipItems[0].xLabel); + } + let date = DateUtils.stringToDate(tooltipItems[0]?.label); return AbstractHistoryChart.toTooltipTitle(service.historyPeriod.value.from, service.historyPeriod.value.to, date, service); }; - let displayValues = chartObject.output(channelData.data); + options = AbstractHistoryChart.applyChartTypeSpecificOptionsChanges(chartType, options, service, chartObject); + + options.scales.x['time'].unit = calculateResolution(service, service.historyPeriod.value.from, service.historyPeriod.value.to).timeFormat; - options.tooltips.callbacks.label = (tooltipItem: TooltipItem, data: Data) => { + options.plugins.tooltip.callbacks.label = (item: Chart.TooltipItem) => { + let label = item.dataset.label; + let value = item.dataset.data[item.dataIndex]; - let label = data.datasets[tooltipItem.datasetIndex].label; - let value = tooltipItem.value; let displayValue = displayValues.find(element => element.name === label.split(":")[0]); - let unit = displayValue?.customUnit + let unit = displayValue?.custom?.unit ?? chartObject.yAxes[0]?.unit; if (value === null) { @@ -710,24 +581,28 @@ export abstract class AbstractHistoryChart implements OnInit { tooltipsLabel = AbstractHistoryChart.getToolTipsAfterTitleLabel(unit, chartType, value, translate); } - // Show floating point number for values between 0 and 1 - // TODO find better workaround for legend labels - return label.split(":")[0] + ": " + AbstractHistoryChart.getToolTipsSuffix(tooltipsLabel, value, chartObject.tooltip.formatNumber, unit, chartType, locale, translate); + return label.split(":")[0] + ": " + AbstractHistoryChart.getToolTipsSuffix(tooltipsLabel, value, displayValue.custom?.formatNumber ?? chartObject.tooltip.formatNumber, unit, chartType, locale, translate, config); }; - // Set Y-Axis Title - options.scales.yAxes[0].scaleLabel.labelString = AbstractHistoryChart.getYAxisTitle(chartObject.yAxes[0]?.unit, translate, chartType); + options.scales.x['time'].unit = calculateResolution(service, service.historyPeriod.value.from, service.historyPeriod.value.to).timeFormat; + + let displayValues = chartObject.output(channelData.data); + options.plugins.tooltip.callbacks.labelColor = (item: Chart.TooltipItem) => { + return { + borderColor: ColorUtils.changeOpacityFromRGBA(item.dataset.borderColor, 1), + backgroundColor: item.dataset.backgroundColor, + }; + }; - // let legendOptions = legendOptions; - options.legend.labels.generateLabels = function (chart: Chart) { + options.plugins.legend.labels.generateLabels = function (chart: Chart.Chart) { - let chartLegendLabelItems: ChartLegendLabelItem[] = []; - chart.data.datasets.forEach((dataset, index) => { + let chartLegendLabelItems: Chart.LegendItem[] = []; + chart.data.datasets.forEach((dataset: Chart.ChartDataset, index) => { let legendItem = legendOptions?.find(element => element.label == dataset.label); + //Remove duplicates like 'directConsumption' from legend + if (chartLegendLabelItems.filter(element => element['text'] == dataset.label).length > 0) { - //Remove duplicates from legend - if (chartLegendLabelItems.filter(element => element.text == dataset.label).length > 0) { return; } @@ -737,11 +612,12 @@ export abstract class AbstractHistoryChart implements OnInit { chartLegendLabelItems.push({ text: dataset.label, datasetIndex: index, - fillStyle: dataset.backgroundColor.toString(), + fontColor: getComputedStyle(document.documentElement).getPropertyValue('--ion-color-text'), + fillStyle: dataset.backgroundColor?.toString(), hidden: isHidden != null ? isHidden : !chart.isDatasetVisible(index), lineWidth: 2, strokeStyle: dataset.borderColor.toString(), - lineDash: dataset.borderDash, + ...(dataset['borderDash'] != null && { lineDash: dataset['borderDash'] }), }); }); }); @@ -749,27 +625,247 @@ export abstract class AbstractHistoryChart implements OnInit { return chartLegendLabelItems; }; - // Remove duplicates from legend, if legendItem with two or more occurrences in legend, use one legendItem to trigger them both - Chart.defaults.global.legend.onClick = function (event: MouseEvent, legendItem: ChartLegendLabelItem) { - let chart: Chart = this.chart; + options.plugins.tooltip.callbacks.afterTitle = function (items: Chart.TooltipItem[]) { + + if (items?.length === 0) { + return null; + } + + // only way to figure out, which stack is active + var tooltipItem = items[0]; // Assuming only one tooltip item is displayed + var datasetIndex = tooltipItem.dataIndex; + // Get the dataset object + var datasets = items.map(element => element.dataset); + + // Assuming the dataset is a bar chart using the 'stacked' option + var stack = items[0].dataset.stack || datasetIndex; + + // If only one item in stack do not show sum of values + if (items.length <= 1) { + return null; + } + + let afterTitle = typeof chartObject.tooltip?.afterTitle == 'function' ? chartObject.tooltip?.afterTitle(stack) : null; + + let totalValue = datasets.filter(el => el.stack == stack).reduce((_total, dataset) => Utils.addSafely(_total, Math.abs(dataset.data[datasetIndex])), 0); + if (afterTitle) { + return afterTitle + ": " + formatNumber(totalValue, 'de', chartObject.tooltip.formatNumber) + ' ' + tooltipsLabel; + } - let legendItems = Chart.defaults.global.legend.labels.generateLabels(this.chart); + return null; + }; - legendItems = legendItems.filter(item => item.text == legendItem.text); - legendItems.forEach(legendItem => { - // original.call(this, event, legendItem1); - setLabelVisible(legendItem.text, !chart.isDatasetVisible(legendItem.datasetIndex)); + // Remove duplicates from legend, if legendItem with two or more occurrences in legend, use one legendItem to trigger them both + options.plugins.legend.onClick = function (event: Chart.ChartEvent, legendItem: Chart.LegendItem, legend) { + let chart: Chart.Chart = this.chart; - var index = legendItem.datasetIndex; - var meta = chart.getDatasetMeta(index); + let legendItems = chart.data.datasets.reduce((arr, ds, i) => { + if (ds.label == legendItem.text) { + arr.push({ label: ds.label, index: i }); + } + return arr; + }, []); + legendItems.forEach(item => { + // original.call(this, event, legendItem1); + setLabelVisible(item.label, !chart.isDatasetVisible(legendItem.datasetIndex)); + var meta = chart.getDatasetMeta(item.index); // See controller.isDatasetVisible comment - meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null; + meta.hidden = meta.hidden === null ? !chart.data.datasets[item.index].hidden : null; }); // We hid a dataset ... rerender the chart chart.update(); }; + + options.scales.x.ticks['source'] = 'auto'; + options.scales.x.ticks.maxTicksLimit = 31; + options.scales.x['bounds'] = 'ticks'; + return options; + } + + + /** + * Gets the yAxis options + * + * @param options the chart options + * @param element the yAxis + * @param translate the translate service + * @param chartType the current chart type + * @param locale the current locale + * @returns the chart options {@link Chart.ChartOptions} + */ + public static getYAxisOptions(options: Chart.ChartOptions, element: HistoryUtils.yAxes, translate: TranslateService, chartType: 'line' | 'bar', locale: string): Chart.ChartOptions { + switch (element.unit) { + + case YAxisTitle.RELAY: + if (chartType === 'line') { + options.scales[element.yAxisId] = { + position: element.position, + min: 0, + max: 1, + beginAtZero: true, + + title: { + text: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), + display: true, + padding: 10, + font: { + size: 11, + }, + }, + + grid: { + display: element.displayGrid ?? true, + }, + ticks: { + color: getComputedStyle(document.documentElement).getPropertyValue('--ion-color-text'), + // Two states are possible + callback: function (value, index, ticks) { + return Converter.ON_OFF(translate)(value); + }, + padding: 5, + stepSize: 20, + }, + }; + } + + if (chartType === 'bar') { + options.scales[element.yAxisId] = { + position: element.position, + min: 0, + beginAtZero: true, + title: { + text: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), + display: true, + padding: 5, + font: { + size: 11, + }, + }, + grid: { + display: element.displayGrid ?? true, + }, + ticks: { + callback: function (value, index, values) { + + if (typeof value !== 'number') { + return; + } + + return TimeUtils.formatSecondsToDuration(value, locale); + }, + }, + }; + } + break; + case YAxisTitle.PERCENTAGE: + options.scales[element.yAxisId] = { + stacked: true, + beginAtZero: true, + max: 100, + min: 0, + type: 'linear', + title: { + text: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), + display: true, + font: { + size: 11, + }, + }, + position: element.position, + grid: { + display: element.displayGrid ?? true, + }, + ticks: { + padding: 5, + stepSize: 20, + }, + }; + break; + + case YAxisTitle.TIME: + options.scales[element.yAxisId] = { + min: 0, + position: element.position, + title: { + text: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), + display: true, + font: { + size: 11, + }, + }, + grid: { + display: element.displayGrid ?? true, + }, + ticks: { + callback: function (value, index, values) { + + if (typeof value === 'number') { + return TimeUtils.formatSecondsToDuration(value, locale); + } + }, + }, + }; + break; + case YAxisTitle.POWER: + case YAxisTitle.ENERGY: + case YAxisTitle.VOLTAGE: + options.scales[element.yAxisId] = { + title: { + text: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), + display: true, + padding: 5, + font: { + size: 11, + }, + }, + position: element.position, + grid: { + display: element.displayGrid ?? true, + }, + ticks: {}, + }; + break; + case YAxisTitle.CURRENCY: + options.scales[element.yAxisId] = { + title: { + text: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), + display: true, + padding: 5, + font: { + size: 11, + }, + }, + position: element.position, + grid: { + display: element.displayGrid ?? true, + }, + beginAtZero: false, + ticks: { + source: 'auto', + }, + }; + break; + case YAxisTitle.NONE: + options.scales[element.yAxisId] = { + title: { + text: element.customTitle ?? AbstractHistoryChart.getYAxisTitle(element.unit, translate, chartType), + display: true, + padding: 5, + font: { + size: 11, + }, + }, + position: element.position, + grid: { + display: element.displayGrid ?? true, + }, + beginAtZero: false, + ticks: {}, + }; + break; + } return options; } @@ -779,7 +875,7 @@ export abstract class AbstractHistoryChart implements OnInit { */ protected setChartLabel() { const locale = this.service.translate.currentLang; - this.options = AbstractHistoryChart.getOptions(this.chartObject, this.chartType, this.service, this.translate, this.legendOptions, this.channelData, locale); + this.options = AbstractHistoryChart.getOptions(this.chartObject, this.chartType, this.service, this.translate, this.legendOptions, this.channelData, locale, this.config); this.loading = false; this.stopSpinner(); } @@ -792,6 +888,10 @@ export abstract class AbstractHistoryChart implements OnInit { this.datasets = HistoryUtils.createEmptyDataset(this.translate); this.labels = []; this.loading = false; + this.options.scales['y'] = { + display: false, + }; + this.stopSpinner(); } @@ -812,11 +912,9 @@ export abstract class AbstractHistoryChart implements OnInit { public static getYAxisTitle(title: YAxisTitle, translate: TranslateService, chartType: 'bar' | 'line', customTitle?: string): string { switch (title) { - case YAxisTitle.CURRENCY: - return customTitle + 'kWh'; case YAxisTitle.RELAY: - if (chartType === ChartType.LINE) { + if (chartType === 'line') { // Hide YAxis title return ''; @@ -835,6 +933,8 @@ export abstract class AbstractHistoryChart implements OnInit { } case YAxisTitle.VOLTAGE: return 'Voltage'; + case YAxisTitle.NONE: + return ''; default: return 'kW'; } @@ -846,7 +946,7 @@ export abstract class AbstractHistoryChart implements OnInit { * @param title the YAxisTitle * @returns */ - private static getToolTipsAfterTitleLabel(title: YAxisTitle | null, chartType: 'bar' | 'line', value: number | null, translate: TranslateService): string { + protected static getToolTipsAfterTitleLabel(title: YAxisTitle | null, chartType: 'bar' | 'line', value: number | string | null, translate: TranslateService): string { switch (title) { case YAxisTitle.RELAY: return Converter.ON_OFF(translate)(value); @@ -873,14 +973,13 @@ export abstract class AbstractHistoryChart implements OnInit { * @param title the YAxisTitle * @returns */ - private static getToolTipsSuffix(label: any, value: number, format: string, title: YAxisTitle, chartType: 'bar' | 'line', language: string, translate: TranslateService): string { + public static getToolTipsSuffix(label: any, value: number, format: string, title: YAxisTitle, chartType: 'bar' | 'line', language: string, translate: TranslateService, config: EdgeConfig): string { let tooltipsLabel: string | null = null; switch (title) { case YAxisTitle.RELAY: - - if (chartType === ChartType.LINE) { + if (chartType === 'line') { return Converter.ON_OFF(translate)(value); } const activeTimeOverPeriodPipe = new FormatSecondsToDurationPipe(new DecimalPipe(language)); @@ -889,12 +988,19 @@ export abstract class AbstractHistoryChart implements OnInit { case YAxisTitle.TIME: const pipe = new FormatSecondsToDurationPipe(new DecimalPipe(language)); return pipe.transform(value); + case YAxisTitle.CURRENCY: + const currency = config.components['_meta'].properties.currency; + tooltipsLabel = Currency.getCurrencyLabelByCurrency(currency); + break; case YAxisTitle.PERCENTAGE: - tooltipsLabel = '%'; + tooltipsLabel = AbstractHistoryChart.getToolTipsAfterTitleLabel(title, chartType, value, translate); break; case YAxisTitle.VOLTAGE: tooltipsLabel = 'V'; break; + case YAxisTitle.POWER: + tooltipsLabel = 'W'; + break; case YAxisTitle.ENERGY: if (chartType == 'bar') { tooltipsLabel = 'kWh'; @@ -902,6 +1008,9 @@ export abstract class AbstractHistoryChart implements OnInit { tooltipsLabel = 'kW'; } break; + default: + tooltipsLabel = ""; + break; } return formatNumber(value, 'de', format) + ' ' + tooltipsLabel; @@ -929,6 +1038,7 @@ export abstract class AbstractHistoryChart implements OnInit { case YAxisTitle.TIME: const pipe = new FormatSecondsToDurationPipe(new DecimalPipe(Language.DE.key)); return baseName + ": " + pipe.transform(suffix); + } } } @@ -986,8 +1096,3 @@ export abstract class AbstractHistoryChart implements OnInit { } protected abstract getChartData(): HistoryUtils.ChartData | null; } - -export enum ChartType { - LINE = 'line', - BAR = 'bar' -} diff --git a/ui/src/app/shared/genericComponents/shared/testing/common.ts b/ui/src/app/shared/genericComponents/shared/testing/common.ts index 4f28edaf548..df13d1a4020 100644 --- a/ui/src/app/shared/genericComponents/shared/testing/common.ts +++ b/ui/src/app/shared/genericComponents/shared/testing/common.ts @@ -1,9 +1,10 @@ import { TimeUnit } from "chart.js"; -import { OeChartTester } from "src/app/shared/genericComponents/shared/testing/tester"; import { QueryHistoricTimeseriesDataResponse } from "src/app/shared/jsonrpc/response/queryHistoricTimeseriesDataResponse"; import { QueryHistoricTimeseriesEnergyPerPeriodResponse } from "src/app/shared/jsonrpc/response/queryHistoricTimeseriesEnergyPerPeriodResponse"; import { QueryHistoricTimeseriesEnergyResponse } from "src/app/shared/jsonrpc/response/queryHistoricTimeseriesEnergyResponse"; +import { OeChartTester } from "./tester"; + export namespace OeTester { export namespace Types { @@ -20,169 +21,17 @@ export namespace OeTester { } export namespace ChartOptions { - export const LINE_CHART_OPTIONS = (period: string, title?: string): OeChartTester.Dataset.Option => ({ + export const LINE_CHART_OPTIONS = (period: string, chartType: 'line' | 'bar', title?: string): OeChartTester.Dataset.Option => ({ type: 'option', options: { - "maintainAspectRatio": false, - "legend": { - "labels": {}, - "position": "bottom", - }, - "elements": { - "point": { - "radius": 0, - "hitRadius": 0, - "hoverRadius": 0, - }, - "line": { - "borderWidth": 2, - "tension": 0.1, - }, - "rectangle": { - "borderWidth": 2, - }, - }, - "hover": { - "mode": "point", - "intersect": true, - }, - "scales": { - "yAxes": [ - { - "id": "left", - "position": "left", - "scaleLabel": { - "display": true, - "labelString": title ?? "kW", - "padding": 5, - "fontSize": 11, - }, - "gridLines": { - "display": true, - }, - "ticks": { - "beginAtZero": false, - }, - }, - ], - "xAxes": [ - { - "ticks": {}, - "stacked": false, - "type": "time", - "time": { - "minUnit": "hour", - "displayFormats": { - "millisecond": "SSS [ms]", - "second": "HH:mm:ss a", - "minute": "HH:mm", - "hour": "HH:[00]", - "day": "DD", - "week": "ll", - "month": "MM", - "quarter": "[Q]Q - YYYY", - "year": "YYYY", - }, - "unit": period as TimeUnit, - }, - "bounds": "ticks", - }, - ], - }, - "tooltips": { - "mode": "index", - "intersect": false, - "axis": "x", - "callbacks": {}, - }, - "responsive": true, + "responsive": true, "maintainAspectRatio": false, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "stepped": false, "fill": true } }, "datasets": { "bar": {}, "line": {} }, "plugins": { "colors": { "enabled": false }, "legend": { "display": true, "position": "bottom", "labels": { "color": '' } }, "tooltip": { "intersect": false, "mode": "index", "callbacks": {} } }, "scales": { "x": { "stacked": true, "offset": false, "type": "time", "ticks": { "source": "auto", "maxTicksLimit": 31 }, "bounds": "ticks", "adapters": { "date": { "locale": { "code": "de", "formatLong": {}, "localize": {}, "match": {}, "options": { "weekStartsOn": 1, "firstWeekContainsDate": 4 } } } }, "time": { "unit": period as TimeUnit, "displayFormats": { "datetime": "yyyy-MM-dd HH:mm:ss", "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:00", "day": "dd", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "yyyy" } } }, "left": { ...(chartType === 'line' ? { stacked: false } : {}), "title": { "text": "kW", "display": true, "padding": 5, "font": { "size": 11 } }, "position": "left", "grid": { "display": true }, "ticks": {} } }, }, }); - export const BAR_CHART_OPTIONS = (period: string, title?: string): OeChartTester.Dataset.Option => ({ + export const BAR_CHART_OPTIONS = (period: string, chartType: 'line' | 'bar', title?: string): OeChartTester.Dataset.Option => ({ type: 'option', options: { - "maintainAspectRatio": false, - "legend": { - "labels": {}, - "position": "bottom", - }, - "elements": { - "point": { - "radius": 0, - "hitRadius": 0, - "hoverRadius": 0, - }, - "line": { - "borderWidth": 2, - "tension": 0.1, - }, - "rectangle": { - "borderWidth": 2, - }, - }, - "hover": { - "mode": "point", - "intersect": true, - }, - "scales": { - "yAxes": [ - { - "id": "left", - "position": "left", - "scaleLabel": { - "display": true, - "labelString": title ?? "kWh", - "padding": 5, - "fontSize": 11, - }, - "gridLines": { - "display": true, - }, - "ticks": { - "beginAtZero": false, - }, - "stacked": true, - }, - ], - "xAxes": [ - { - "ticks": { - "maxTicksLimit": 12, - "source": "data", - }, - "stacked": true, - "type": "time", - "time": { - "minUnit": "hour", - "displayFormats": { - "millisecond": "SSS [ms]", - "second": "HH:mm:ss a", - "minute": "HH:mm", - "hour": "HH:[00]", - "day": "DD", - "week": "ll", - "month": "MM", - "quarter": "[Q]Q - YYYY", - "year": "YYYY", - }, - "unit": period as TimeUnit, - }, - "offset": true, - "bounds": "ticks", - }, - ], - }, - "tooltips": { - "mode": "x", - "intersect": false, - "axis": "x", - "callbacks": {}, - }, - "responsive": true, + "responsive": true, "maintainAspectRatio": false, "elements": { "point": { "radius": 0, "hitRadius": 0, "hoverRadius": 0 }, "line": { "stepped": false, "fill": true } }, "datasets": { "bar": { "barPercentage": 1 }, "line": {} }, "plugins": { "colors": { "enabled": false }, "legend": { "display": true, "position": "bottom", "labels": { "color": '' } }, "tooltip": { "intersect": false, "mode": "x", "callbacks": {} } }, "scales": { "x": { "stacked": true, "offset": true, "type": "time", "ticks": { "source": "auto", "maxTicksLimit": 31 }, "bounds": "ticks", "adapters": { "date": { "locale": { "code": "de", "formatLong": {}, "localize": {}, "match": {}, "options": { "weekStartsOn": 1, "firstWeekContainsDate": 4 } } } }, "time": { "unit": period as TimeUnit, "displayFormats": { "datetime": "yyyy-MM-dd HH:mm:ss", "millisecond": "SSS [ms]", "second": "HH:mm:ss a", "minute": "HH:mm", "hour": "HH:00", "day": "dd", "week": "ll", "month": "MM", "quarter": "[Q]Q - YYYY", "year": "yyyy" } } }, "left": { ...(chartType === 'line' ? { stacked: false } : {}), "title": { "text": "kWh", "display": true, "padding": 5, "font": { "size": 11 } }, "position": "left", "grid": { "display": true }, "ticks": {} } }, }, }); } - - - } diff --git a/ui/src/app/shared/genericComponents/shared/testing/tester.ts b/ui/src/app/shared/genericComponents/shared/testing/tester.ts index 8eeca21ed61..d65a86d2c4f 100644 --- a/ui/src/app/shared/genericComponents/shared/testing/tester.ts +++ b/ui/src/app/shared/genericComponents/shared/testing/tester.ts @@ -1,9 +1,9 @@ -import { ChartDataSets } from "chart.js"; -import { ChartOptions } from "src/app/edge/history/shared"; +import * as Chart from "chart.js"; +import { ChartDataset } from "chart.js"; import { QueryHistoricTimeseriesDataResponse } from "src/app/shared/jsonrpc/response/queryHistoricTimeseriesDataResponse"; import { QueryHistoricTimeseriesEnergyPerPeriodResponse } from "src/app/shared/jsonrpc/response/queryHistoricTimeseriesEnergyPerPeriodResponse"; import { HistoryUtils } from "src/app/shared/service/utils"; -import { CurrentData } from "src/app/shared/shared"; +import { CurrentData, EdgeConfig } from "src/app/shared/shared"; import { TestContext } from "src/app/shared/test/utils.spec"; import { AbstractHistoryChart } from "../../chart/abstracthistorychart"; @@ -215,14 +215,14 @@ export namespace OeChartTester { } export type Option = { type: 'option', - options: ChartOptions + options: Chart.ChartOptions } } } export class OeChartTester { - public static apply(chartData: HistoryUtils.ChartData, chartType: 'line' | 'bar', channels: OeTester.Types.Channels, testContext: TestContext): OeChartTester.View { + public static apply(chartData: HistoryUtils.ChartData, chartType: 'line' | 'bar', channels: OeTester.Types.Channels, testContext: TestContext, config: EdgeConfig): OeChartTester.View { let channelData = OeChartTester.getChannelDataByCharttype(chartType, channels); @@ -237,7 +237,7 @@ export class OeChartTester { let configuration = AbstractHistoryChart.fillChart(chartType, chartData, channelData, channels.energyChannelWithValues); let data: OeChartTester.Dataset.Data[] = OeChartTester.convertChartDatasetsToDatasets(configuration.datasets); let labels: OeChartTester.Dataset.LegendLabel = OeChartTester.convertChartLabelsToLegendLabels(configuration.labels); - let options: OeChartTester.Dataset.Option = OeChartTester.convertChartDataToOptions(chartData, chartType, testContext, channels, testContext.translate.currentLang); + let options: OeChartTester.Dataset.Option = OeChartTester.convertChartDataToOptions(chartData, chartType, testContext, channels, testContext.translate.currentLang, config); return { datasets: { @@ -267,7 +267,7 @@ export class OeChartTester { * @param datasets the datasets * @returns data from a chartData dataset */ - public static convertChartDatasetsToDatasets(datasets: ChartDataSets[]): OeChartTester.Dataset.Data[] { + public static convertChartDatasetsToDatasets(datasets: ChartDataset[]): OeChartTester.Dataset.Data[] { let fields: OeChartTester.Dataset.Data[] = []; for (let dataset of datasets) { @@ -291,7 +291,7 @@ export class OeChartTester { * @param channels the channels * @returns dataset options */ - public static convertChartDataToOptions(chartData: HistoryUtils.ChartData, chartType: 'line' | 'bar', testContext: TestContext, channels: OeTester.Types.Channels, locale: string): OeChartTester.Dataset.Option { + public static convertChartDataToOptions(chartData: HistoryUtils.ChartData, chartType: 'line' | 'bar', testContext: TestContext, channels: OeTester.Types.Channels, locale: string, config: EdgeConfig): OeChartTester.Dataset.Option { let channelData: QueryHistoricTimeseriesDataResponse | QueryHistoricTimeseriesEnergyPerPeriodResponse = OeChartTester.getChannelDataByCharttype(chartType, channels); let displayValues = chartData.output(channelData.result.data); @@ -305,7 +305,7 @@ export class OeChartTester { return { type: 'option', - options: AbstractHistoryChart.getOptions(chartData, chartType, testContext.service, testContext.translate, legendOptions, channelData.result, locale), + options: AbstractHistoryChart.getOptions(chartData, chartType, testContext.service, testContext.translate, legendOptions, channelData.result, locale, config), }; } diff --git a/ui/src/app/shared/pipe/formatSecondsToDuration/formatSecondsToDuration.pipe.ts b/ui/src/app/shared/pipe/formatSecondsToDuration/formatSecondsToDuration.pipe.ts index 0d2f431ed06..acc42e39c2c 100644 --- a/ui/src/app/shared/pipe/formatSecondsToDuration/formatSecondsToDuration.pipe.ts +++ b/ui/src/app/shared/pipe/formatSecondsToDuration/formatSecondsToDuration.pipe.ts @@ -1,6 +1,8 @@ import { DecimalPipe } from '@angular/common'; import { Pipe, PipeTransform } from '@angular/core'; +import { Converter } from '../../genericComponents/shared/converter'; + @Pipe({ name: 'formatSecondsToDuration', }) @@ -9,13 +11,17 @@ export class FormatSecondsToDurationPipe implements PipeTransform { constructor(private decimalPipe: DecimalPipe) { } transform(value: number): string { - let minutes = value / 60; - let hours = Math.floor(minutes / 60); - minutes -= hours * 60; - if (hours <= 23) { - return this.decimalPipe.transform(hours, '1.0-0') + 'h' + " " + this.decimalPipe.transform(minutes, '1.0-0') + 'm'; - } else { - return this.decimalPipe.transform(hours, '1.0-0') + 'h'; - } + + return Converter.IF_NUMBER(value, (val) => { + let minutes = val / 60; + let hours = Math.floor(minutes / 60); + minutes -= hours * 60; + if (hours <= 23) { + return this.decimalPipe.transform(hours, '1.0-0') + 'h' + " " + this.decimalPipe.transform(minutes, '1.0-0') + 'm'; + } else { + return this.decimalPipe.transform(hours, '1.0-0') + 'h'; + } + }); } + } diff --git a/ui/src/app/shared/service/utils.ts b/ui/src/app/shared/service/utils.ts index c93fe5131ee..03c6b2ecd04 100644 --- a/ui/src/app/shared/service/utils.ts +++ b/ui/src/app/shared/service/utils.ts @@ -1,10 +1,9 @@ import { formatNumber } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; -import { ChartDataSets } from 'chart.js'; +import { ChartDataset } from 'chart.js'; import { saveAs } from 'file-saver-es'; import { DefaultTypes } from 'src/app/shared/service/defaulttypes'; -import { ChartType } from '../genericComponents/chart/abstracthistorychart'; import { JsonrpcResponseSuccess } from '../jsonrpc/base'; import { Base64PayloadResponse } from '../jsonrpc/response/base64PayloadResponse'; import { QueryHistoricTimeseriesEnergyResponse } from '../jsonrpc/response/queryHistoricTimeseriesEnergyResponse'; @@ -611,6 +610,8 @@ export class Utils { } export enum YAxisTitle { + NONE, + POWER, PERCENTAGE, RELAY, ENERGY, @@ -635,7 +636,7 @@ export namespace HistoryUtils { * @param translate the TranslateService * @returns a dataset */ - export function createEmptyDataset(translate: TranslateService): ChartDataSets[] { + export function createEmptyDataset(translate: TranslateService): ChartDataset[] { return [{ label: translate.instant("Edge.History.noData"), data: [], @@ -675,10 +676,15 @@ export namespace HistoryUtils { hideShadow?: boolean, /** axisId from yAxes */ yAxisId?: ChartAxis, - /** overrides global unit for this displayValue */ - customUnit?: YAxisTitle, - /** overrides global charttype for this dataset */ - customType?: ChartType, + /** overrides global chartConfig for this dataset */ + custom?: { + /** overrides global unit */ + unit?: YAxisTitle, + /** overrides global charttype */ + type?: 'line' | 'bar', + /** overrides global formatNumber */ + formatNumber?: string + }, tooltip?: [{ afterTitle: (channelData?: { [name: string]: number[] }) => string, stackIds: number[] @@ -764,7 +770,7 @@ export namespace HistoryUtils { export namespace TimeOfUseTariffUtils { export type ScheduleChartData = { - datasets: ChartDataSets[], + datasets: ChartDataset[], colors: any[], labels: Date[] } @@ -810,7 +816,7 @@ export namespace TimeOfUseTariffUtils { * @returns The ScheduleChartData. */ export function getScheduleChartData(size: number, prices: number[], states: number[], timestamps: string[], translate: TranslateService, controlMode: ControlMode): ScheduleChartData { - const datasets: ChartDataSets[] = []; + const datasets: ChartDataset[] = []; const colors: any[] = []; const labels: Date[] = []; diff --git a/ui/src/app/shared/shared.module.ts b/ui/src/app/shared/shared.module.ts index dcc03d594e8..2c14ab7e406 100644 --- a/ui/src/app/shared/shared.module.ts +++ b/ui/src/app/shared/shared.module.ts @@ -7,7 +7,7 @@ import { IonicModule } from '@ionic/angular'; import { FormlyFieldConfig, FormlyModule } from '@ngx-formly/core'; import { FormlyIonicModule } from '@ngx-formly/ionic'; import { TranslateModule } from '@ngx-translate/core'; -import { ChartsModule } from 'ng2-charts'; +import { NgChartsModule } from 'ng2-charts'; import { NgxSpinnerModule } from "ngx-spinner"; import { appRoutingProviders } from './../app-routing.module'; @@ -57,7 +57,7 @@ export function SubnetmaskValidatorMessage(err, field: FormlyFieldConfig) { @NgModule({ imports: [ BrowserAnimationsModule, - ChartsModule, + NgChartsModule, CommonModule, DirectiveModule, FormsModule, @@ -120,7 +120,7 @@ export function SubnetmaskValidatorMessage(err, field: FormlyFieldConfig) { exports: [ // modules BrowserAnimationsModule, - ChartsModule, + NgChartsModule, CommonModule, DirectiveModule, FormlyIonicModule, diff --git a/ui/src/app/shared/test/utils.spec.ts b/ui/src/app/shared/test/utils.spec.ts index 261e23a6836..a94f83dbc00 100644 --- a/ui/src/app/shared/test/utils.spec.ts +++ b/ui/src/app/shared/test/utils.spec.ts @@ -5,8 +5,6 @@ import { LOCALE_ID } from "@angular/core"; import { TestBed } from "@angular/core/testing"; import { FORMLY_CONFIG } from "@ngx-formly/core"; import { TranslateLoader, TranslateModule, TranslateService } from "@ngx-translate/core"; -import { setDefaultOptions } from 'date-fns'; -import { de } from "date-fns/locale"; import { Service } from "../shared"; import { registerTranslateExtension } from "../translate.extension"; @@ -27,9 +25,8 @@ export async function sharedSetup(): Promise { ], }).compileComponents().then(() => { const translateService = TestBed.inject(TranslateService); - translateService.addLangs(['en', 'de']); + translateService.addLangs(['de']); translateService.use('de'); - setDefaultOptions({ locale: de }); registerLocaleData(localDE, 'de', localeDeExtra); }); diff --git a/ui/src/app/shared/utils/color/color.utils.spec.ts b/ui/src/app/shared/utils/color/color.utils.spec.ts new file mode 100644 index 00000000000..3e2c43ad324 --- /dev/null +++ b/ui/src/app/shared/utils/color/color.utils.spec.ts @@ -0,0 +1,17 @@ +import { ColorUtils } from "./color.utils"; + +describe('Color-Utils', () => { + it('#rgbStringToRgba', () => { + expect(ColorUtils.rgbStringToRGBA('rgb(0,0,0)', 1)).toBe('rgba(0,0,0,1)'); + expect(ColorUtils.rgbStringToRGBA('rgb(0,0,0)', null)).toEqual('rgba(0,0,0,0)'); + expect(ColorUtils.rgbStringToRGBA(null, 1)).toEqual(null); + expect(ColorUtils.rgbStringToRGBA(null, null)).toEqual(null); + }); + + it('#changeOpacityFromRGBA', () => { + expect(ColorUtils.changeOpacityFromRGBA('rgba(0,0,0,0.05)', 1)).toBe('rgba(0,0,0,1)'); + expect(ColorUtils.changeOpacityFromRGBA('rgba(0,0,0,0.05)', null)).toBe('rgba(0,0,0,0)'); + expect(ColorUtils.changeOpacityFromRGBA(null, 1)).toBe(null); + expect(ColorUtils.changeOpacityFromRGBA(null, null)).toBe(null); + }); +}); diff --git a/ui/src/app/shared/utils/color/color.utils.ts b/ui/src/app/shared/utils/color/color.utils.ts new file mode 100644 index 00000000000..cd424a03897 --- /dev/null +++ b/ui/src/app/shared/utils/color/color.utils.ts @@ -0,0 +1,37 @@ +export namespace ColorUtils { + + /** + * Converts a rgb-string into a rgba-string + * + * @param color the color + * @param opacity the opacity + * @returns a string in rgba format + */ + export function rgbStringToRGBA(color: string, opacity: number): string { + + if (!color) { + return null; + } + + return 'rgba(' + color.split('(').pop().split(')')[0] + ',' + (opacity ?? 0) + ')'; + } + + /** + * Changes opacity of a passed rgba string + * + * @param color the color + * @param opacity the opacity + * @returns a string in rgba format + */ + export function changeOpacityFromRGBA(color: string, opacity: number): string { + + if (!color) { + return null; + } + + var rgba = color.split('(').pop().split(')')[0]; + var rgb = rgba.split(',').slice(0, -1).join(','); + + return 'rgba(' + rgb + ',' + (opacity ?? 0) + ')'; + } +} diff --git a/ui/src/app/shared/utils/date/dateutils.ts b/ui/src/app/shared/utils/date/dateutils.ts index b9f519514a7..8c4925b181f 100644 --- a/ui/src/app/shared/utils/date/dateutils.ts +++ b/ui/src/app/shared/utils/date/dateutils.ts @@ -72,4 +72,8 @@ export namespace DateUtils { export function toLocaleTimeString(date: Date): string { return date.toLocaleTimeString(); } + + export function isFullHour(date: Date) { + return date.getMinutes() != 0 ? null : date; + } } diff --git a/ui/src/assets/i18n/de.json b/ui/src/assets/i18n/de.json index 4857f24842d..5d607d0f561 100644 --- a/ui/src/assets/i18n/de.json +++ b/ui/src/assets/i18n/de.json @@ -577,9 +577,10 @@ "DOWNLOAD_ERROR": "Das Protokoll konnte nicht heruntergeladen werden", "DOWNLOAD": "IBN-Protokoll herunterladen", "SUB_TITLE": "Sie haben den {{ value }} erfolgreich in Betrieb genommen.", - "TITLE": "Abschließen" + "TITLE": "Abschließen", + "NOTE": "Hier geht's weiter zum App Center, um weitere Komponenten zu konfigurieren und Apps zu installieren." }, - "COMPLETE": "abschließen", + "COMPLETE": "Zum Online-Monitoring", "CONFIGURATION_EMERGENCY_RESERVE": { "EMERGENCY_RESERVE_NOTE": "Wenn diese Funktion aktiviert ist, kann der Ladezustand der Batterie nicht unter den eingestellten Wert fallen.", "EMERGENCY_RESERVE_VALUE": "Notstrom wert", @@ -597,7 +598,6 @@ "BATTERY": "Batterie", "COMMUNICATION_WITH_BATTERY_INVERTER": "Kommunikation mit dem Batterie-Wechselrichter", "COMMUNICATION_WITH_BATTERY": "Kommunikation mit der Batterie", - "CONFIGURATION_SUCCESS": "Konfiguration erfolgreich.", "DESCRIPTION_1": "Um sicherzustellen, dass alle Komponenten Ihres Systems korrekt eingerichtet werden,", "DESCRIPTION_2": "können die Konfiguration und die nachfolgenden Funktionstests bis zu 10 Minuten in Anspruch nehmen.", "EMERGENCY_CAPACITY_RESERVE": "Ansteuerung der Notstromreserve", @@ -621,7 +621,6 @@ "SURPLUS_ENERGY_FEEDIN": "Überschusseinspeisung", "TITLE": "Konfiguration", "WAITING": "Konfiguration läuft...", - "WILL_BE_CONFIGURED": "wird konfiguriert / ausgeführt", "POWER": "Power", "COMMUNICATION_WITH_METER": "Kommunikation mit den Zählern", "WAGO_BRIDGE": "Wago Bridge", @@ -662,9 +661,7 @@ "PRODUCER": "Erzeuger", "SUMMARY": "Zusammenfassung", "TIME_OF_INSTALLATION": "Zeitpunkt der Installation", - "VALUE_AC": "Wert AC", "WARRANTY_TERMS": "Garantiebedingungen", - "PEAK_SHAVING": "Lastspitzenkappung", "APPS": "Apps", "HECKERT": "Ihre gewählte kostenlose App", "ACCEPT": "akzeptieren", @@ -672,7 +669,11 @@ "VALUE_WITH_LABEL_HOME_DC": "Wert MPPT{{ mppt }} PV{{ pv }} {{ symbol }}", "ORIENTATION_WITH_LABEL_HOME_DC": "Ausrichtung MPPT{{ mppt }} PV{{ pv }}", "MODULE_TYPE_WITH_LABEL_HOME_DC": "Modultyp MPPT{{ mppt }} PV{{ pv }}", - "NUMBER_OF_MODULES_WITH_LABEL_HOME_DC": "Anzahl PV-Module MPPT{{ mppt }} PV{{ pv }}" + "NUMBER_OF_MODULES_WITH_LABEL_HOME_DC": "Anzahl PV-Module MPPT{{ mppt }} PV{{ pv }}", + "DEVICE_CONNECTION_CHECKED": "Das Stromspeichersystem ist an das Stromnetz angeschlossen", + "ENERGY_FLOW_METER": { + "LABEL": "Installierter Netzzähler" + } }, "CONFIGURATION_SYSTEM": { "OPEN_INSTRUCTIONS": "Anleitung öffnen", @@ -738,10 +739,8 @@ "TITLE_INSTALLER": "Kontaktdaten Installateur", "ZIP": "PLZ" }, - "PROTOCOL_PV_AND_ADDITIONAL_AC": { - "ADD": "Erzeuger hinzufügen", + "PROTOCOL_PV": { "ADDITIONAL_GENERATOR": "Zusätzliche AC-Erzeuger", - "ALIAS_DESCRIPTION_ADDITIONAL_AC": "z. B. \"PV Hausdach\"", "ALIAS_DESCRIPTION_PV": "wird im Online-Monitoring angezeigt, z. B. \"PV Hausdach\"", "ALIAS": "Bezeichnung", "DIRECTIONS": { @@ -756,12 +755,6 @@ }, "INSTALLED_POWER": "Installierte leistung [Wₚ]", "MARKED_AS": " MPPT {{ mppt }} (beschriftet mit \"PV{{ pv }}\")", - "METER_TYPE_WITH_LABEL": "Zählertyp {{ label }}{{ number }}", - "METER_TYPE": "Zählertyp", - "MODBUS_SOCOMEC_DESCRIPTION": "Der Zähler muss mit den folgenden Parametern konfiguriert werden: Kommunikationsgeschwindigkeit (baud) \"9600\", Kommunikationsparität (PrtY) \"n\", Kommunikations-Stopbit (StoP) \"1\"", - "MODBUS_KDK_DESCRIPTION": "Der Zähler muss mit den folgenden Parametern konfiguriert werden: Kommunikationsgeschwindigkeit (baud) \"9600\", Kommunikationsparität (PrtY) \"e\", Kommunikations-Stopbit (StoP) \"1\"", - "MODBUS_WITH_LABEL": "Modbus Kommunikationsadresse {{ label }}{{ number }}", - "MODBUS": "Modbus Kommunikationsadresse", "MODULE_TYPE_DESCRIPTION": "z. B. Hersteller und Leistung", "MODULE_TYPE_WITH_LABEL": "Modultyp {{ label }}{{ number }}", "MODULE_TYPE": "Modultyp", @@ -770,16 +763,10 @@ "OPEN_MANUAL": "Anleitung öffnen", "ORIENTATION_WITH_LABEL": "Ausrichtung {{ label }}{{ number }}", "ORIENTATION": "Ausrichtung", - "SAVE_TO_CONTINUE": "Speichern Sie zuerst Ihre Eingaben um fortzufahren.", - "SAVE": "Erzeuger speichern", "SHADE_MANAGEMENT_DEACTIVATE": "Schattenmanagement deaktivieren", "SHADE_MANAGEMENT_DESCRIPTION": "Nur wenn Optimierer verbaut sind, muss das Schattenmanagement deaktiviert werden", - "TITLE_ADDITIONAL_AC": "AC-Erzeuger", "TITLE_PV": "DC-PV Installation (Wechselrichtereingänge)", - "VALID_DATA": "Geben Sie gültige Daten ein, um zu speichern.", "TITLE_DC": "DC-PV-Installation", - "AC_NOT_CREATED": "AC zähler nicht erstellt!", - "METER_SELECTION_WARNING": "Bitte wählen Sie den Zähler aus, indem Sie den Erzeuger hinzufügen.", "DUPLICATE": " MPPT {{ mppt }} doppelt belegt (beschriftet mit \"PV{{ pv }}\")" }, "PROTOCOL_SERIAL_NUMBERS": { @@ -828,22 +815,7 @@ "VALUE_WITH_LABEL": "Wert {{ label }}{{ number }} {{ symbol }}", "ALIAS_WITH_LABEL": "Alias {{label}}{{number}}", "CONFIGURATION_FEATURES_STORAGE_SYSTEM": { - "BALANCING": "Eigenverbrauchsoptimierung", - "PEAK_SHAVING_SYMMETRIC": "Lastspitzenkappung", - "PEAK_SHAVING_ASYMMETRIC": "Phasengenaue Lastspitzenkappung", - "FEATURE_DESCRIPTION": "Die entsprechende App muss vorhanden sein", - "HEADER": "Angaben zum Einsatz des Speichers", - "PEAK_SHAVING_SYMMETRIC_HEADER": "Einstellungen Lastspitzenkappung", - "PEAK_SHAVING_ASYMMETRIC_HEADER": "Einstellungen Phasen Genaue Lastspitzenkappung" - }, - "CONFIGURATION_PEAK_SHAVING": { - "DISCHARGE_ABOVE_VALUE": "Beladung unter - Wert [W]", - "CHARGE_BELOW_VALUE": "Beladung unter - Wert [W]", - "DISCHARGE_ABOVE_DESCRIPTION": "liegt die Netzbezugsleistung oberhalb von diesem Wert, wird die Batterie entladen.", - "CHARGE_BELOW_DESCRIPTION": "liegt die Netzbezugsleistung unterhalb von diesem Wert, wird die Batterie wieder beladen.\nDieser Wert darf max. dem Wert \"Entladung über\" entsprechen.", - "DESCRIPTION": "Eingetragene Leistungswerte beziehen sich auf einzelne Phasen. Es wird auf die jeweils am stärksten belastete Phase ausgeregelt.", - "DISCHARGE_ABOVE_LABEL": "Entladung über", - "CHARGE_BELOW_LABEL": "Beladung unter" + "BALANCING": "Eigenverbrauchsoptimierung" }, "CLICK_RECOMMENDATION": "Bitte klicken Sie unten auf den \"Hinzufügen\"-Button wenn sie ein {{ edgeShortName }} in Betrieb nehmen wollen.", "CONFIGURATION_COMMERCIAL_MODBUS_COMPONENT": { @@ -852,7 +824,17 @@ }, "CONFIGURATION_COMMERCIAL_MODBUS_BRIDGE": { "HEADER": "Auswahl der Kommunikationsart" - } + }, + "CONFIGURATION_ENERGY_FLOW_METER": { + "TITLE": "Auswahl Energieflussrichtungszähler", + "METER": { + "WITH_CT": "Home 3-Phasensensor mit Stromwandler 120 A (Standardlieferumfang)", + "WITHOUT_CT": "Home 3-Phasensensor ohne Stromwandler (Optional)", + "LABEL": "Zähler" + }, + "CONVERTER_RATIO": "Primärstrom (200–5000A)" + }, + "CONFIGURATION_MPPT_SELECTION_NOTE": "Weitere Erzeuger können im Anschluss über das App Center konfiguriert werden." }, "Login": { "title": "Login", @@ -919,7 +901,7 @@ "emailNotEqual": "E-Mails stimmen nicht überein" }, "success": "Registrierung erfolgreich", - "createUser": "Installateurszugang anlegen" + "createUser": "Account anlegen" }, "Role": { "guest": "Gast", diff --git a/ui/src/assets/i18n/en.json b/ui/src/assets/i18n/en.json index 1b6d4e32975..87b3211ee40 100644 --- a/ui/src/assets/i18n/en.json +++ b/ui/src/assets/i18n/en.json @@ -574,12 +574,13 @@ "INSTALLATION": { "ATTENTION_MESSAGE": "Note that the selection cannot be undone afterwards.", "BACK": "Back", - "COMPLETE": "complete", + "COMPLETE": "To Online-Monitoring", "COMPLETION": { "DOWNLOAD_ERROR": "The Protocol could not be downloaded", "DOWNLOAD": "IBN-Protocol download", "SUB_TITLE": "You have successfully commisioned the {{ value }}.", - "TITLE": "Set-up complete" + "TITLE": "Set-up complete", + "NOTE": "Click here to go to the App Center to configure additional components and install apps." }, "CONFIGURATION_EMERGENCY_RESERVE": { "EMERGENCY_RESERVE_NOTE": "If this function is activated, the battery charge level cannot fall below the set value.", @@ -621,7 +622,6 @@ "SURPLUS_ENERGY_FEEDIN": "Surplus energy feed-in", "TITLE": "Configuration", "WAITING": "Configuration running...", - "WILL_BE_CONFIGURED": "Will be configured / checked", "POWER": "Power", "COMMUNICATION_WITH_METER": "Communication with the Meter", "WAGO_BRIDGE": "Wago Bridge", @@ -662,9 +662,7 @@ "PRODUCER": "Generator", "SUMMARY": "Summary", "TIME_OF_INSTALLATION": "Time of the installation", - "VALUE_AC": "Value AC", "WARRANTY_TERMS": "Warranty terms", - "PEAK_SHAVING": "Peak shaving", "APPS": "Apps", "HECKERT": "Your chosen free app", "ACCEPT": "acceptation", @@ -672,7 +670,11 @@ "VALUE_WITH_LABEL_HOME_DC": "Value MPPT{{ mppt }} PV{{ pv }} {{ symbol }}", "ORIENTATION_WITH_LABEL_HOME_DC": "MPPT{{ mppt }} PV{{ pv }} Orientation", "MODULE_TYPE_WITH_LABEL_HOME_DC": "Type of modules MPPT{{ mppt }} PV{{ pv }}", - "NUMBER_OF_MODULES_WITH_LABEL_HOME_DC": "Numnber of PV modules MPPT{{ mppt }} PV{{ pv }}" + "NUMBER_OF_MODULES_WITH_LABEL_HOME_DC": "Numnber of PV modules MPPT{{ mppt }} PV{{ pv }}", + "DEVICE_CONNECTION_CHECKED": "The energy storage system is connected to the power grid", + "ENERGY_FLOW_METER": { + "LABEL": "Installed Grid-Meter" + } }, "CONFIGURATION_SYSTEM": { "OPEN_INSTRUCTIONS": "Open instructions", @@ -738,10 +740,8 @@ "TITLE_INSTALLER": "Contact data - Installer", "ZIP": "ZIP code" }, - "PROTOCOL_PV_AND_ADDITIONAL_AC": { - "ADD": "Add generator", + "PROTOCOL_PV": { "ADDITIONAL_GENERATOR": "Additional AC-Generator", - "ALIAS_DESCRIPTION_ADDITIONAL_AC": "e.g. \"PV-Roof\"", "ALIAS_DESCRIPTION_PV": "will be displayed in the Online-Monitoring, e.g. \"PV-Roof\"", "ALIAS": "Description", "DIRECTIONS": { @@ -756,12 +756,6 @@ }, "INSTALLED_POWER": "Installed power[Wₚ]", "MARKED_AS": " MPPT {{ mppt }} (marked as \"PV{{ pv }}\")", - "METER_TYPE_WITH_LABEL": "Type of the sensor {{ label }}{{ number }}", - "METER_TYPE": "Type of the sensor", - "MODBUS_SOCOMEC_DESCRIPTION": "The sensor has to be configured with the following settings: Communication speed (baud) \"9600\", Communication parity (partY) \"n\", Communication Stopbit (StoP) \"1\"", - "MODBUS_KDK_DESCRIPTION": "The sensor has to be configured with the following settings: Communication speed (baud) \"9600\", Communication parity (partY) \"e\", Communication Stopbit (StoP) \"1\"", - "MODBUS_WITH_LABEL": "Modbus {{ label }}{{ number }}", - "MODBUS": "Modbus", "MODULE_TYPE_DESCRIPTION": "e.g. Manufuturer and Power", "MODULE_TYPE_WITH_LABEL": "Type of modules {{ label }}{{ number }}", "MODULE_TYPE": "Type of modules", @@ -770,16 +764,10 @@ "OPEN_MANUAL": "Open manual", "ORIENTATION_WITH_LABEL": "{{ label }}{{ number }} Orientation", "ORIENTATION": "Orientation", - "SAVE_TO_CONTINUE": "First save your entries to continue.", - "SAVE": "Save generator", "SHADE_MANAGEMENT_DEACTIVATE": "Deactivate Shade management", "SHADE_MANAGEMENT_DESCRIPTION": "The shade management has to be disabled, only if optimizers are installed.", - "TITLE_ADDITIONAL_AC": "AC-Generator", "TITLE_PV": "DC-PV installation (Inverter inputs)", - "VALID_DATA": "Enter valid data to save.", "TITLE_DC": "DC-PV-Installation", - "AC_NOT_CREATED": "AC Meter not created!", - "METER_SELECTION_WARNING": "Please select the meter by adding generator.", "DUPLICATE": " MPPT {{ mppt }} double occupied (marked as \"PV{{ pv }}\")" }, "PROTOCOL_SERIAL_NUMBERS": { @@ -828,22 +816,7 @@ "VALUE_WITH_LABEL": "Value {{ label }}{{ number }} {{ symbol }}", "ALIAS_WITH_LABEL": "Alias {{label}}{{number}}", "CONFIGURATION_FEATURES_STORAGE_SYSTEM": { - "BALANCING": "Self-Consumption optmization", - "PEAK_SHAVING_SYMMETRIC": "Peak shaving", - "PEAK_SHAVING_ASYMMETRIC": "Phase Accurate Peak shaving", - "FEATURE_DESCRIPTION": "The corresponding App must be available", - "HEADER": "Information on the use of the Storage system", - "PEAK_SHAVING_SYMMETRIC_HEADER": "Peak load shaving settings", - "PEAK_SHAVING_ASYMMETRIC_HEADER": "Phases Accurate peak shaving settings" - }, - "CONFIGURATION_PEAK_SHAVING": { - "DISCHARGE_ABOVE_VALUE": "Discharging above - Value [W]", - "CHARGE_BELOW_VALUE": "Charging below - Value [W]", - "DISCHARGE_ABOVE_DESCRIPTION": "If the grid power is above this value, the battery will be discharged.", - "CHARGE_BELOW_DESCRIPTION": "if the grid power is below this value, the battery is charged again.\nThis value must not exceed the \"Discharge over\" value.", - "DESCRIPTION": "Entered power values refer to individual phases. It is adjusted to the most heavily loaded phase.", - "DISCHARGE_ABOVE_LABEL": "Discharge above", - "CHARGE_BELOW_LABEL": "Charge below" + "BALANCING": "Self-Consumption optmization" }, "CLICK_RECOMMENDATION": "Please click on the \"Add\" button below if you want to commission a {{ edgeShortName }}.", "CONFIGURATION_COMMERCIAL_MODBUS_COMPONENT": { @@ -852,7 +825,17 @@ }, "CONFIGURATION_COMMERCIAL_MODBUS_BRIDGE": { "HEADER": "Select the type of Communication" - } + }, + "CONFIGURATION_ENERGY_FLOW_METER": { + "TITLE": "Selection of energy flow direction meter", + "METER": { + "WITH_CT": "Home 3-phase sensor with current transformer 120A (standard scope of delivery)", + "WITHOUT_CT": "Home 3-phase sensor without current transformer (optional)", + "LABEL": "Meter" + }, + "CONVERTER_RATIO": "Converter ratio (200–5000A)" + }, + "CONFIGURATION_MPPT_SELECTION_NOTE": "Additional generators can then be configured via the App Center." }, "Login": { "title": "Login", @@ -920,7 +903,7 @@ "emailNotEqual": "E-Mails are not equal" }, "success": "Registration successful", - "createUser": "Create installer account" + "createUser": "Create account" }, "Role": { "guest": "Guest", diff --git a/ui/src/environments/index.ts b/ui/src/environments/index.ts index b1b4762efad..7ca279f35ae 100644 --- a/ui/src/environments/index.ts +++ b/ui/src/environments/index.ts @@ -44,33 +44,36 @@ export interface Environment { readonly SETTINGS_ALERTING: string, readonly SETTINGS_NETWORK_CONFIGURATION: string, - readonly warranty: { - readonly home: { + readonly WARRANTY: { + readonly HOME: { readonly EN: string, readonly DE: string, }, - readonly commercial: { + readonly COMMERCIAL: { readonly EN: string, readonly DE: string, } } - readonly gtc: { + readonly GTC: { readonly EN: string, readonly DE: string }, - readonly METER_SOCOMEC: string, + readonly METER: { + readonly SOCOMEC: string, + readonly KDK: string + }, readonly MANUALS: { readonly HOME: { - readonly EN: string, - readonly DE: string, + readonly HOME_10: string, + readonly HOME_20_30: string, }, readonly COMMERCIAL: { - readonly EN: string, - readonly DE: string, - } + readonly COMMERCIAL_30: string, + readonly COMMERCIAL_50: string, + }, }, APP_CENTER: { /** diff --git a/ui/src/themes/openems/environments/theme.ts b/ui/src/themes/openems/environments/theme.ts index ffc2b91911f..783195597a3 100644 --- a/ui/src/themes/openems/environments/theme.ts +++ b/ui/src/themes/openems/environments/theme.ts @@ -33,33 +33,35 @@ export const theme = { SETTINGS_NETWORK_CONFIGURATION: null, EVCS_CLUSTER: "io.openems.edge.evcs.cluster/readme.adoc", - warranty: { - home: { + WARRANTY: { + HOME: { EN: "#", DE: "#", }, - commercial: { + COMMERCIAL: { EN: "#", DE: "#", }, }, - gtc: { + GTC: { EN: "#", DE: "#", }, - // Currently the links are different with different prefixes. so adding whole url for Socomec. - METER_SOCOMEC: null, + METER: { + SOCOMEC: "#", + KDK: "#", + }, MANUALS: { HOME: { - EN: "#", - DE: "#", + HOME_10: "#", + HOME_20_30: "#", }, COMMERCIAL: { - EN: "#", - DE: "#", + COMMERCIAL_30: "#", + COMMERCIAL_50: "#", }, }, APP_CENTER: { diff --git a/ui/src/themes/openems/scss/variables.scss b/ui/src/themes/openems/scss/variables.scss index b66fa02139a..936fd07be47 100644 --- a/ui/src/themes/openems/scss/variables.scss +++ b/ui/src/themes/openems/scss/variables.scss @@ -84,6 +84,7 @@ $font-family: var(--ion-font-family); /** font **/ --ion-font-family: "Roboto", "Helvetica Neue", sans-serif; --ion-color-background: #fff; + --ion-color-text: #444444; } /** Custom Colors **/ @@ -119,4 +120,4 @@ $font-family: var(--ion-font-family); --ion-color-shade: var(--ion-color-production-shade); --ion-color-tint: var(--ion-color-production-tint); } -} \ No newline at end of file +}