+
{countryNames[code]}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 92285c63..999cea03 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -4,7 +4,6 @@ import '@fontsource/inter/400.css';
import '@fontsource/inter/700.css';
import '@fontsource/inter/800.css';
import 'react-basics/dist/styles.css';
-import 'styles/locale.css';
import 'styles/index.css';
import 'styles/variables.css';
diff --git a/src/components/charts/BarChart.tsx b/src/components/charts/BarChart.tsx
index 7624ba1c..eadc4af7 100644
--- a/src/components/charts/BarChart.tsx
+++ b/src/components/charts/BarChart.tsx
@@ -7,6 +7,7 @@ import { useMemo, useState } from 'react';
export interface BarChartProps extends ChartProps {
unit: string;
stacked?: boolean;
+ currency?: string;
renderXLabel?: (label: string, index: number, values: any[]) => string;
renderYLabel?: (label: string, index: number, values: any[]) => string;
XAxisType?: string;
@@ -27,6 +28,7 @@ export function BarChart(props: BarChartProps) {
stacked = false,
minDate,
maxDate,
+ currency,
} = props;
const options: any = useMemo(() => {
@@ -76,7 +78,9 @@ export function BarChart(props: BarChartProps) {
const handleTooltip = ({ tooltip }: { tooltip: any }) => {
const { opacity } = tooltip;
- setTooltip(opacity ? : null);
+ setTooltip(
+ opacity ? : null,
+ );
};
return (
diff --git a/src/components/charts/BarChartTooltip.tsx b/src/components/charts/BarChartTooltip.tsx
index fed5af92..201c6e4c 100644
--- a/src/components/charts/BarChartTooltip.tsx
+++ b/src/components/charts/BarChartTooltip.tsx
@@ -1,7 +1,7 @@
-import { formatDate } from 'lib/date';
-import { Flexbox, StatusLight } from 'react-basics';
-import { formatLongNumber } from 'lib/format';
import { useLocale } from 'components/hooks';
+import { formatDate } from 'lib/date';
+import { formatLongCurrency, formatLongNumber } from 'lib/format';
+import { Flexbox, StatusLight } from 'react-basics';
const formats = {
millisecond: 'T',
@@ -15,7 +15,7 @@ const formats = {
year: 'yyyy',
};
-export default function BarChartTooltip({ tooltip, unit }) {
+export default function BarChartTooltip({ tooltip, unit, currency }) {
const { locale } = useLocale();
const { labelColors, dataPoints } = tooltip;
@@ -26,7 +26,10 @@ export default function BarChartTooltip({ tooltip, unit }) {
- {formatLongNumber(dataPoints[0].raw.y)} {dataPoints[0].dataset.label}
+ {currency
+ ? formatLongCurrency(dataPoints[0].raw.y, currency)
+ : formatLongNumber(dataPoints[0].raw.y)}{' '}
+ {dataPoints[0].dataset.label}
diff --git a/src/components/hooks/index.ts b/src/components/hooks/index.ts
index 1be99732..7c16eeee 100644
--- a/src/components/hooks/index.ts
+++ b/src/components/hooks/index.ts
@@ -1,9 +1,7 @@
-export * from './queries/useApi';
export * from './queries/useConfig';
export * from './queries/useEventDataEvents';
export * from './queries/useEventDataProperties';
export * from './queries/useEventDataValues';
-export * from './queries/usePagedQuery';
export * from './queries/useLogin';
export * from './queries/useRealtime';
export * from './queries/useReport';
@@ -28,6 +26,7 @@ export * from './queries/useWebsiteEvents';
export * from './queries/useWebsiteEventsSeries';
export * from './queries/useWebsiteMetrics';
export * from './queries/useWebsiteValues';
+export * from './useApi';
export * from './useCountryNames';
export * from './useDateRange';
export * from './useDocumentClick';
@@ -41,6 +40,7 @@ export * from './useLocale';
export * from './useMessages';
export * from './useModified';
export * from './useNavigation';
+export * from './usePagedQuery';
export * from './useRegionNames';
export * from './useSticky';
export * from './useTeamUrl';
diff --git a/src/components/hooks/queries/useConfig.ts b/src/components/hooks/queries/useConfig.ts
index 72fe095d..f6293a44 100644
--- a/src/components/hooks/queries/useConfig.ts
+++ b/src/components/hooks/queries/useConfig.ts
@@ -1,6 +1,6 @@
import { useEffect } from 'react';
import useStore, { setConfig } from 'store/app';
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
let loading = false;
diff --git a/src/components/hooks/queries/useEventDataEvents.ts b/src/components/hooks/queries/useEventDataEvents.ts
index 1d7ccf2d..5cad9916 100644
--- a/src/components/hooks/queries/useEventDataEvents.ts
+++ b/src/components/hooks/queries/useEventDataEvents.ts
@@ -1,4 +1,4 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
import { UseQueryOptions } from '@tanstack/react-query';
import { useFilterParams } from '../useFilterParams';
diff --git a/src/components/hooks/queries/useEventDataProperties.ts b/src/components/hooks/queries/useEventDataProperties.ts
index 4eabd051..b841a8f4 100644
--- a/src/components/hooks/queries/useEventDataProperties.ts
+++ b/src/components/hooks/queries/useEventDataProperties.ts
@@ -1,5 +1,5 @@
-import useApi from './useApi';
import { UseQueryOptions } from '@tanstack/react-query';
+import { useApi } from '../useApi';
import { useFilterParams } from '../useFilterParams';
export function useEventDataProperties(
diff --git a/src/components/hooks/queries/useEventDataValues.ts b/src/components/hooks/queries/useEventDataValues.ts
index 61aea58e..de6783a0 100644
--- a/src/components/hooks/queries/useEventDataValues.ts
+++ b/src/components/hooks/queries/useEventDataValues.ts
@@ -1,5 +1,5 @@
-import useApi from './useApi';
import { UseQueryOptions } from '@tanstack/react-query';
+import { useApi } from '../useApi';
import { useFilterParams } from '../useFilterParams';
export function useEventDataValues(
@@ -12,7 +12,7 @@ export function useEventDataValues(
const params = useFilterParams(websiteId);
return useQuery({
- queryKey: ['websites:event-data:values', { websiteId, propertyName, ...params }],
+ queryKey: ['websites:event-data:values', { websiteId, eventName, propertyName, ...params }],
queryFn: () =>
get(`/websites/${websiteId}/event-data/values`, { ...params, eventName, propertyName }),
enabled: !!(websiteId && propertyName),
diff --git a/src/components/hooks/queries/useLogin.ts b/src/components/hooks/queries/useLogin.ts
index c17687b0..a54f38d1 100644
--- a/src/components/hooks/queries/useLogin.ts
+++ b/src/components/hooks/queries/useLogin.ts
@@ -1,6 +1,6 @@
-import useStore, { setUser } from 'store/app';
-import useApi from './useApi';
import { UseQueryResult } from '@tanstack/react-query';
+import useStore, { setUser } from 'store/app';
+import { useApi } from '../useApi';
const selector = (state: { user: any }) => state.user;
diff --git a/src/components/hooks/queries/useRealtime.ts b/src/components/hooks/queries/useRealtime.ts
index 9c665e4f..b87f74c4 100644
--- a/src/components/hooks/queries/useRealtime.ts
+++ b/src/components/hooks/queries/useRealtime.ts
@@ -1,7 +1,7 @@
import { useTimezone } from 'components/hooks';
import { REALTIME_INTERVAL } from 'lib/constants';
import { RealtimeData } from 'lib/types';
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
export function useRealtime(websiteId: string) {
const { get, useQuery } = useApi();
diff --git a/src/components/hooks/queries/useReport.ts b/src/components/hooks/queries/useReport.ts
index 2e63e4e6..f7d2a1a0 100644
--- a/src/components/hooks/queries/useReport.ts
+++ b/src/components/hooks/queries/useReport.ts
@@ -1,6 +1,6 @@
import { produce } from 'immer';
import { useCallback, useEffect, useState } from 'react';
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
import { useTimezone } from '../useTimezone';
import { useMessages } from '../useMessages';
diff --git a/src/components/hooks/queries/useReports.ts b/src/components/hooks/queries/useReports.ts
index 88e4f02e..21db1536 100644
--- a/src/components/hooks/queries/useReports.ts
+++ b/src/components/hooks/queries/useReports.ts
@@ -1,5 +1,5 @@
-import useApi from './useApi';
-import usePagedQuery from './usePagedQuery';
+import useApi from '../useApi';
+import usePagedQuery from '../usePagedQuery';
import useModified from '../useModified';
export function useReports({ websiteId, teamId }: { websiteId?: string; teamId?: string }) {
diff --git a/src/components/hooks/queries/useRevenueValues.ts b/src/components/hooks/queries/useRevenueValues.ts
new file mode 100644
index 00000000..007ca3c5
--- /dev/null
+++ b/src/components/hooks/queries/useRevenueValues.ts
@@ -0,0 +1,18 @@
+import { useApi } from '../useApi';
+
+export function useRevenueValues(websiteId: string, startDate: Date, endDate: Date) {
+ const { get, useQuery } = useApi();
+
+ return useQuery({
+ queryKey: ['revenue:values', { websiteId, startDate, endDate }],
+ queryFn: () =>
+ get(`/reports/revenue`, {
+ websiteId,
+ startDate,
+ endDate,
+ }),
+ enabled: !!(websiteId && startDate && endDate),
+ });
+}
+
+export default useRevenueValues;
diff --git a/src/components/hooks/queries/useSessionActivity.ts b/src/components/hooks/queries/useSessionActivity.ts
index 16c139ab..1c9c8f57 100644
--- a/src/components/hooks/queries/useSessionActivity.ts
+++ b/src/components/hooks/queries/useSessionActivity.ts
@@ -1,4 +1,4 @@
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
export function useSessionActivity(
websiteId: string,
diff --git a/src/components/hooks/queries/useSessionData.ts b/src/components/hooks/queries/useSessionData.ts
index 14e046d1..521ba7d5 100644
--- a/src/components/hooks/queries/useSessionData.ts
+++ b/src/components/hooks/queries/useSessionData.ts
@@ -1,4 +1,4 @@
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
export function useSessionData(websiteId: string, sessionId: string) {
const { get, useQuery } = useApi();
diff --git a/src/components/hooks/queries/useSessionDataProperties.ts b/src/components/hooks/queries/useSessionDataProperties.ts
index 459dccd6..45590b39 100644
--- a/src/components/hooks/queries/useSessionDataProperties.ts
+++ b/src/components/hooks/queries/useSessionDataProperties.ts
@@ -1,4 +1,4 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
import { UseQueryOptions } from '@tanstack/react-query';
import { useFilterParams } from '../useFilterParams';
diff --git a/src/components/hooks/queries/useSessionDataValues.ts b/src/components/hooks/queries/useSessionDataValues.ts
index ce9a67f3..85529fc0 100644
--- a/src/components/hooks/queries/useSessionDataValues.ts
+++ b/src/components/hooks/queries/useSessionDataValues.ts
@@ -1,4 +1,4 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
import { UseQueryOptions } from '@tanstack/react-query';
import { useFilterParams } from '../useFilterParams';
diff --git a/src/components/hooks/queries/useShareToken.ts b/src/components/hooks/queries/useShareToken.ts
index 189657be..f9db7dbf 100644
--- a/src/components/hooks/queries/useShareToken.ts
+++ b/src/components/hooks/queries/useShareToken.ts
@@ -1,5 +1,5 @@
import useStore, { setShareToken } from 'store/app';
-import useApi from './useApi';
+import { useApi } from '../useApi';
const selector = (state: { shareToken: string }) => state.shareToken;
diff --git a/src/components/hooks/queries/useTeam.ts b/src/components/hooks/queries/useTeam.ts
index e348531c..d0ce7499 100644
--- a/src/components/hooks/queries/useTeam.ts
+++ b/src/components/hooks/queries/useTeam.ts
@@ -1,4 +1,4 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
export function useTeam(teamId: string) {
const { get, useQuery } = useApi();
diff --git a/src/components/hooks/queries/useTeamMembers.ts b/src/components/hooks/queries/useTeamMembers.ts
index a3e8bcd2..b6353afc 100644
--- a/src/components/hooks/queries/useTeamMembers.ts
+++ b/src/components/hooks/queries/useTeamMembers.ts
@@ -1,5 +1,5 @@
-import useApi from './useApi';
-import usePagedQuery from './usePagedQuery';
+import { useApi } from '../useApi';
+import usePagedQuery from '../usePagedQuery';
import useModified from '../useModified';
export function useTeamMembers(teamId: string) {
diff --git a/src/components/hooks/queries/useTeamWebsites.ts b/src/components/hooks/queries/useTeamWebsites.ts
index fac82d13..5606407e 100644
--- a/src/components/hooks/queries/useTeamWebsites.ts
+++ b/src/components/hooks/queries/useTeamWebsites.ts
@@ -1,5 +1,5 @@
-import useApi from './useApi';
-import usePagedQuery from './usePagedQuery';
+import { useApi } from '../useApi';
+import { usePagedQuery } from '../usePagedQuery';
import useModified from '../useModified';
export function useTeamWebsites(teamId: string) {
diff --git a/src/components/hooks/queries/useTeams.ts b/src/components/hooks/queries/useTeams.ts
index e1f7790a..e5197c97 100644
--- a/src/components/hooks/queries/useTeams.ts
+++ b/src/components/hooks/queries/useTeams.ts
@@ -1,5 +1,5 @@
-import useApi from './useApi';
-import usePagedQuery from './usePagedQuery';
+import { useApi } from '../useApi';
+import { usePagedQuery } from '../usePagedQuery';
import useModified from '../useModified';
export function useTeams(userId: string) {
diff --git a/src/components/hooks/queries/useUser.ts b/src/components/hooks/queries/useUser.ts
index 61c22ecd..8541a220 100644
--- a/src/components/hooks/queries/useUser.ts
+++ b/src/components/hooks/queries/useUser.ts
@@ -1,4 +1,4 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
export function useUser(userId: string, options?: { [key: string]: any }) {
const { get, useQuery } = useApi();
diff --git a/src/components/hooks/queries/useUsers.ts b/src/components/hooks/queries/useUsers.ts
index 519fb899..3d70d262 100644
--- a/src/components/hooks/queries/useUsers.ts
+++ b/src/components/hooks/queries/useUsers.ts
@@ -1,5 +1,5 @@
-import useApi from './useApi';
-import usePagedQuery from './usePagedQuery';
+import { useApi } from '../useApi';
+import { usePagedQuery } from '../usePagedQuery';
import useModified from '../useModified';
export function useUsers() {
diff --git a/src/components/hooks/queries/useWebsite.ts b/src/components/hooks/queries/useWebsite.ts
index 4121f97b..9151b55d 100644
--- a/src/components/hooks/queries/useWebsite.ts
+++ b/src/components/hooks/queries/useWebsite.ts
@@ -1,4 +1,4 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
export function useWebsite(websiteId: string, options?: { [key: string]: any }) {
const { get, useQuery } = useApi();
diff --git a/src/components/hooks/queries/useWebsiteEvents.ts b/src/components/hooks/queries/useWebsiteEvents.ts
index 5d9bd196..2a47c3eb 100644
--- a/src/components/hooks/queries/useWebsiteEvents.ts
+++ b/src/components/hooks/queries/useWebsiteEvents.ts
@@ -1,7 +1,7 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
import { UseQueryOptions } from '@tanstack/react-query';
import { useFilterParams } from '../useFilterParams';
-import { usePagedQuery } from './usePagedQuery';
+import { usePagedQuery } from '../usePagedQuery';
export function useWebsiteEvents(
websiteId: string,
diff --git a/src/components/hooks/queries/useWebsiteEventsSeries.ts b/src/components/hooks/queries/useWebsiteEventsSeries.ts
index 88b49375..91c50fff 100644
--- a/src/components/hooks/queries/useWebsiteEventsSeries.ts
+++ b/src/components/hooks/queries/useWebsiteEventsSeries.ts
@@ -1,4 +1,4 @@
-import useApi from './useApi';
+import { useApi } from '../useApi';
import { UseQueryOptions } from '@tanstack/react-query';
import { useFilterParams } from '../useFilterParams';
diff --git a/src/components/hooks/queries/useWebsiteMetrics.ts b/src/components/hooks/queries/useWebsiteMetrics.ts
index 184fd4d4..1a4202e8 100644
--- a/src/components/hooks/queries/useWebsiteMetrics.ts
+++ b/src/components/hooks/queries/useWebsiteMetrics.ts
@@ -1,6 +1,7 @@
import { UseQueryOptions } from '@tanstack/react-query';
-import useApi from './useApi';
+import { useApi } from '../useApi';
import { useFilterParams } from '../useFilterParams';
+import { useSearchParams } from 'next/navigation';
export function useWebsiteMetrics(
websiteId: string,
@@ -9,6 +10,7 @@ export function useWebsiteMetrics(
) {
const { get, useQuery } = useApi();
const params = useFilterParams(websiteId);
+ const searchParams = useSearchParams();
return useQuery({
queryKey: [
@@ -20,12 +22,9 @@ export function useWebsiteMetrics(
},
],
queryFn: async () => {
- const filters = { ...params };
-
- filters[queryParams.type] = undefined;
-
const data = await get(`/websites/${websiteId}/metrics`, {
- ...filters,
+ ...params,
+ [searchParams.get('view')]: undefined,
...queryParams,
});
diff --git a/src/components/hooks/queries/useWebsitePageviews.ts b/src/components/hooks/queries/useWebsitePageviews.ts
index c9260bcb..42fb527e 100644
--- a/src/components/hooks/queries/useWebsitePageviews.ts
+++ b/src/components/hooks/queries/useWebsitePageviews.ts
@@ -1,5 +1,5 @@
import { UseQueryOptions } from '@tanstack/react-query';
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
import { useFilterParams } from '..//useFilterParams';
export function useWebsitePageviews(
diff --git a/src/components/hooks/queries/useWebsiteSession.ts b/src/components/hooks/queries/useWebsiteSession.ts
index 64c7be58..93e9057c 100644
--- a/src/components/hooks/queries/useWebsiteSession.ts
+++ b/src/components/hooks/queries/useWebsiteSession.ts
@@ -1,4 +1,4 @@
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
export function useWebsiteSession(websiteId: string, sessionId: string) {
const { get, useQuery } = useApi();
diff --git a/src/components/hooks/queries/useWebsiteSessionStats.ts b/src/components/hooks/queries/useWebsiteSessionStats.ts
index 7671b2eb..5c02cfdc 100644
--- a/src/components/hooks/queries/useWebsiteSessionStats.ts
+++ b/src/components/hooks/queries/useWebsiteSessionStats.ts
@@ -1,4 +1,4 @@
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
import { useFilterParams } from '../useFilterParams';
export function useWebsiteSessionStats(websiteId: string, options?: { [key: string]: string }) {
diff --git a/src/components/hooks/queries/useWebsiteSessions.ts b/src/components/hooks/queries/useWebsiteSessions.ts
index ce65512c..ad7bb616 100644
--- a/src/components/hooks/queries/useWebsiteSessions.ts
+++ b/src/components/hooks/queries/useWebsiteSessions.ts
@@ -1,5 +1,5 @@
-import { useApi } from './useApi';
-import { usePagedQuery } from './usePagedQuery';
+import { useApi } from '../useApi';
+import { usePagedQuery } from '../usePagedQuery';
import useModified from '../useModified';
import { useFilterParams } from 'components/hooks/useFilterParams';
diff --git a/src/components/hooks/queries/useWebsiteSessionsWeekly.ts b/src/components/hooks/queries/useWebsiteSessionsWeekly.ts
index 5df543f5..c4e83f98 100644
--- a/src/components/hooks/queries/useWebsiteSessionsWeekly.ts
+++ b/src/components/hooks/queries/useWebsiteSessionsWeekly.ts
@@ -1,4 +1,4 @@
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
import useModified from '../useModified';
import { useFilterParams } from 'components/hooks/useFilterParams';
diff --git a/src/components/hooks/queries/useWebsiteStats.ts b/src/components/hooks/queries/useWebsiteStats.ts
index b24399fa..6d42009e 100644
--- a/src/components/hooks/queries/useWebsiteStats.ts
+++ b/src/components/hooks/queries/useWebsiteStats.ts
@@ -1,4 +1,4 @@
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
import { useFilterParams } from '../useFilterParams';
export function useWebsiteStats(
diff --git a/src/components/hooks/queries/useWebsiteValues.ts b/src/components/hooks/queries/useWebsiteValues.ts
index c5358df2..68e950f2 100644
--- a/src/components/hooks/queries/useWebsiteValues.ts
+++ b/src/components/hooks/queries/useWebsiteValues.ts
@@ -1,4 +1,4 @@
-import { useApi } from './useApi';
+import { useApi } from '../useApi';
export function useWebsiteValues({
websiteId,
diff --git a/src/components/hooks/queries/useWebsites.ts b/src/components/hooks/queries/useWebsites.ts
index d6fe00df..7a5004d7 100644
--- a/src/components/hooks/queries/useWebsites.ts
+++ b/src/components/hooks/queries/useWebsites.ts
@@ -1,5 +1,5 @@
-import { useApi } from './useApi';
-import { usePagedQuery } from './usePagedQuery';
+import { useApi } from '../useApi';
+import { usePagedQuery } from '../usePagedQuery';
import { useLogin } from './useLogin';
import useModified from '../useModified';
diff --git a/src/components/hooks/queries/useApi.ts b/src/components/hooks/useApi.ts
similarity index 100%
rename from src/components/hooks/queries/useApi.ts
rename to src/components/hooks/useApi.ts
diff --git a/src/components/hooks/useDateRange.ts b/src/components/hooks/useDateRange.ts
index 248070f4..23cb6e70 100644
--- a/src/components/hooks/useDateRange.ts
+++ b/src/components/hooks/useDateRange.ts
@@ -5,7 +5,7 @@ import websiteStore, { setWebsiteDateRange, setWebsiteDateCompare } from 'store/
import appStore, { setDateRange } from 'store/app';
import { DateRange } from 'lib/types';
import { useLocale } from './useLocale';
-import { useApi } from './queries/useApi';
+import { useApi } from './useApi';
export function useDateRange(websiteId?: string): {
dateRange: DateRange;
diff --git a/src/components/hooks/useFields.ts b/src/components/hooks/useFields.ts
index e6fc54b3..859ca1ce 100644
--- a/src/components/hooks/useFields.ts
+++ b/src/components/hooks/useFields.ts
@@ -15,6 +15,7 @@ export function useFields() {
{ name: 'region', type: 'string', label: formatMessage(labels.region) },
{ name: 'city', type: 'string', label: formatMessage(labels.city) },
{ name: 'host', type: 'string', label: formatMessage(labels.host) },
+ { name: 'tag', type: 'string', label: formatMessage(labels.tag) },
];
return { fields };
diff --git a/src/components/hooks/useFilterParams.ts b/src/components/hooks/useFilterParams.ts
index 525f3492..55deed14 100644
--- a/src/components/hooks/useFilterParams.ts
+++ b/src/components/hooks/useFilterParams.ts
@@ -7,7 +7,21 @@ export function useFilterParams(websiteId: string) {
const { startDate, endDate, unit } = dateRange;
const { timezone, toUtc } = useTimezone();
const {
- query: { url, referrer, title, query, host, os, browser, device, country, region, city, event },
+ query: {
+ url,
+ referrer,
+ title,
+ query,
+ host,
+ os,
+ browser,
+ device,
+ country,
+ region,
+ city,
+ event,
+ tag,
+ },
} = useNavigation();
return {
@@ -27,5 +41,6 @@ export function useFilterParams(websiteId: string) {
region,
city,
event,
+ tag,
};
}
diff --git a/src/components/hooks/queries/usePagedQuery.ts b/src/components/hooks/usePagedQuery.ts
similarity index 94%
rename from src/components/hooks/queries/usePagedQuery.ts
rename to src/components/hooks/usePagedQuery.ts
index 253f8092..19471432 100644
--- a/src/components/hooks/queries/usePagedQuery.ts
+++ b/src/components/hooks/usePagedQuery.ts
@@ -1,8 +1,8 @@
import { UseQueryOptions } from '@tanstack/react-query';
import { useState } from 'react';
-import { useApi } from './useApi';
import { PageResult, PageParams, PagedQueryResult } from 'lib/types';
-import { useNavigation } from '../useNavigation';
+import { useApi } from './useApi';
+import { useNavigation } from './useNavigation';
export function usePagedQuery({
queryKey,
diff --git a/src/components/input/LanguageButton.tsx b/src/components/input/LanguageButton.tsx
index fcaa4046..5da3bf78 100644
--- a/src/components/input/LanguageButton.tsx
+++ b/src/components/input/LanguageButton.tsx
@@ -1,4 +1,4 @@
-import { Icon, Button, PopupTrigger, Popup, Text } from 'react-basics';
+import { Icon, Button, PopupTrigger, Popup } from 'react-basics';
import classNames from 'classnames';
import { languages } from 'lib/lang';
import { useLocale } from 'components/hooks';
@@ -33,7 +33,7 @@ export function LanguageButton() {
className={classNames(styles.item, { [styles.selected]: value === locale })}
onClick={(e: any) => handleSelect(value, close, e)}
>
- {label}
+ {label}
{value === locale && (
diff --git a/src/components/messages.ts b/src/components/messages.ts
index f711a4f6..688dd11d 100644
--- a/src/components/messages.ts
+++ b/src/components/messages.ts
@@ -98,6 +98,7 @@ export const labels = defineMessages({
devices: { id: 'label.devices', defaultMessage: 'Devices' },
countries: { id: 'label.countries', defaultMessage: 'Countries' },
languages: { id: 'label.languages', defaultMessage: 'Languages' },
+ tags: { id: 'label.tags', defaultMessage: 'Tags' },
count: { id: 'label.count', defaultMessage: 'Count' },
average: { id: 'label.average', defaultMessage: 'Average' },
sum: { id: 'label.sum', defaultMessage: 'Sum' },
@@ -114,8 +115,6 @@ export const labels = defineMessages({
none: { id: 'label.none', defaultMessage: 'None' },
clearAll: { id: 'label.clear-all', defaultMessage: 'Clear all' },
property: { id: 'label.property', defaultMessage: 'Property' },
- revenueProperty: { id: 'label.revenue-property', defaultMessage: 'Revenue Property' },
- userProperty: { id: 'label.user-property', defaultMessage: 'User Property' },
today: { id: 'label.today', defaultMessage: 'Today' },
lastHours: { id: 'label.last-hours', defaultMessage: 'Last {x} hours' },
yesterday: { id: 'label.yesterday', defaultMessage: 'Yesterday' },
@@ -153,6 +152,7 @@ export const labels = defineMessages({
regions: { id: 'label.regions', defaultMessage: 'Regions' },
reports: { id: 'label.reports', defaultMessage: 'Reports' },
eventData: { id: 'label.event-data', defaultMessage: 'Event data' },
+ sessionData: { id: 'label.session-data', defaultMessage: 'Session data' },
funnel: { id: 'label.funnel', defaultMessage: 'Funnel' },
funnelDescription: {
id: 'label.funnel-description',
@@ -161,8 +161,9 @@ export const labels = defineMessages({
revenue: { id: 'label.revenue', defaultMessage: 'Revenue' },
revenueDescription: {
id: 'label.revenue-description',
- defaultMessage: 'Look into your revenue across time.',
+ defaultMessage: 'Look into your revenue data and how users are spending.',
},
+ currency: { id: 'label.currency', defaultMessage: 'Currency' },
url: { id: 'label.url', defaultMessage: 'URL' },
urls: { id: 'label.urls', defaultMessage: 'URLs' },
path: { id: 'label.path', defaultMessage: 'Path' },
@@ -220,6 +221,7 @@ export const labels = defineMessages({
browser: { id: 'label.browser', defaultMessage: 'Browser' },
device: { id: 'label.device', defaultMessage: 'Device' },
pageTitle: { id: 'label.pageTitle', defaultMessage: 'Page title' },
+ tag: { id: 'label.tag', defaultMessage: 'Tag' },
day: { id: 'label.day', defaultMessage: 'Day' },
date: { id: 'label.date', defaultMessage: 'Date' },
pageOf: { id: 'label.page-of', defaultMessage: 'Page {current} of {total}' },
diff --git a/src/components/metrics/CountriesTable.tsx b/src/components/metrics/CountriesTable.tsx
index 592ade8a..c1fc2831 100644
--- a/src/components/metrics/CountriesTable.tsx
+++ b/src/components/metrics/CountriesTable.tsx
@@ -12,12 +12,7 @@ export function CountriesTable({ ...props }: MetricsTableProps) {
const renderLink = ({ x: code }) => {
return (
-
+
);
diff --git a/src/components/metrics/HostsTable.tsx b/src/components/metrics/HostsTable.tsx
index d3a0f3bf..45147eac 100644
--- a/src/components/metrics/HostsTable.tsx
+++ b/src/components/metrics/HostsTable.tsx
@@ -25,7 +25,7 @@ export function HostsTable(props: MetricsTableProps) {
{...props}
title={formatMessage(labels.hosts)}
type="host"
- metric={formatMessage(labels.views)}
+ metric={formatMessage(labels.visitors)}
renderLabel={renderLink}
/>
>
diff --git a/src/components/metrics/LanguagesTable.tsx b/src/components/metrics/LanguagesTable.tsx
index 67b6e622..f4b0b503 100644
--- a/src/components/metrics/LanguagesTable.tsx
+++ b/src/components/metrics/LanguagesTable.tsx
@@ -13,7 +13,7 @@ export function LanguagesTable({
const languageNames = useLanguageNames(locale);
const renderLabel = ({ x }) => {
- return {languageNames[x?.split('-')[0]] ?? x}
;
+ return languageNames[x?.split('-')[0]] ?? x;
};
return (
diff --git a/src/components/metrics/Legend.tsx b/src/components/metrics/Legend.tsx
index c7ef1022..4ebcf4b4 100644
--- a/src/components/metrics/Legend.tsx
+++ b/src/components/metrics/Legend.tsx
@@ -3,7 +3,6 @@ import { safeDecodeURIComponent } from 'next-basics';
import { colord } from 'colord';
import classNames from 'classnames';
import { LegendItem } from 'chart.js/auto';
-import { useLocale } from 'components/hooks';
import styles from './Legend.module.css';
export function Legend({
@@ -13,8 +12,6 @@ export function Legend({
items: any[];
onClick: (index: LegendItem) => void;
}) {
- const { locale } = useLocale();
-
if (!items.find(({ text }) => text)) {
return null;
}
@@ -32,7 +29,7 @@ export function Legend({
onClick={() => onClick(item)}
>
- {safeDecodeURIComponent(text)}
+ {safeDecodeURIComponent(text)}
);
diff --git a/src/components/metrics/RegionsTable.tsx b/src/components/metrics/RegionsTable.tsx
index 215551af..b4071f50 100644
--- a/src/components/metrics/RegionsTable.tsx
+++ b/src/components/metrics/RegionsTable.tsx
@@ -11,7 +11,7 @@ export function RegionsTable(props: MetricsTableProps) {
const renderLink = ({ x: code, country }) => {
return (
-
+
);
diff --git a/src/components/metrics/TagsTable.tsx b/src/components/metrics/TagsTable.tsx
new file mode 100644
index 00000000..a1130bb4
--- /dev/null
+++ b/src/components/metrics/TagsTable.tsx
@@ -0,0 +1,30 @@
+import MetricsTable, { MetricsTableProps } from './MetricsTable';
+import FilterLink from 'components/common/FilterLink';
+import { useMessages } from 'components/hooks';
+import { Flexbox } from 'react-basics';
+
+export function TagsTable(props: MetricsTableProps) {
+ const { formatMessage, labels } = useMessages();
+
+ const renderLink = ({ x: tag }) => {
+ return (
+
+
+
+ );
+ };
+
+ return (
+ <>
+
+ >
+ );
+}
+
+export default TagsTable;
diff --git a/src/lang/cs-CZ.json b/src/lang/cs-CZ.json
index 717bd970..8adc5e36 100644
--- a/src/lang/cs-CZ.json
+++ b/src/lang/cs-CZ.json
@@ -1,88 +1,88 @@
{
- "label.access-code": "Access code",
+ "label.access-code": "Přístupový kód",
"label.actions": "Akce",
- "label.activity": "Activity log",
- "label.add": "Add",
- "label.add-description": "Add description",
- "label.add-member": "Add member",
- "label.add-step": "Add step",
+ "label.activity": "Log aktivity",
+ "label.add": "Přidat",
+ "label.add-description": "Přidat popis",
+ "label.add-member": "Přidat člena",
+ "label.add-step": "Přidat krok",
"label.add-website": "Přidat web",
"label.admin": "Administrátor",
- "label.after": "After",
+ "label.after": "Po",
"label.all": "Vše",
- "label.all-time": "All time",
+ "label.all-time": "Celá doba",
"label.analytics": "Analytics",
- "label.average": "Average",
+ "label.average": "Průměr",
"label.back": "Zpět",
- "label.before": "Before",
+ "label.before": "Před",
"label.bounce-rate": "Okamžité opuštění",
"label.breakdown": "Breakdown",
- "label.browser": "Browser",
- "label.browsers": "Prohlížeč",
+ "label.browser": "Prohlížeč",
+ "label.browsers": "Prohlížeče",
"label.cancel": "Zrušit",
"label.change-password": "Změnit heslo",
- "label.cities": "Cities",
- "label.city": "City",
- "label.clear-all": "Clear all",
- "label.compare": "Compare",
- "label.confirm": "Confirm",
+ "label.cities": "Města",
+ "label.city": "Město",
+ "label.clear-all": "Vyčistit vše",
+ "label.compare": "Porovnat",
+ "label.confirm": "Potvrdit",
"label.confirm-password": "Potvrdit heslo",
- "label.contains": "Contains",
- "label.continue": "Continue",
- "label.count": "Count",
- "label.countries": "Země",
- "label.country": "Country",
- "label.create": "Create",
- "label.create-report": "Create report",
- "label.create-team": "Create team",
- "label.create-user": "Create user",
- "label.created": "Created",
+ "label.contains": "Obsahuje",
+ "label.continue": "Pokračovat",
+ "label.count": "Počet",
+ "label.countries": "Státy",
+ "label.country": "Stát",
+ "label.create": "Vytvořit",
+ "label.create-report": "Vytvořit hlášení",
+ "label.create-team": "Vytvořit tým",
+ "label.create-user": "Vytvořit uživatele",
+ "label.created": "Vytvořeno",
"label.created-by": "Created By",
- "label.current": "Current",
+ "label.current": "Aktuální",
"label.current-password": "Aktuální heslo",
"label.custom-range": "Vlastní rozsah",
"label.dashboard": "Přehled",
"label.data": "Data",
- "label.date": "Date",
+ "label.date": "Datum",
"label.date-range": "Období",
- "label.day": "Day",
+ "label.day": "Den",
"label.default-date-range": "Výchozí období",
"label.delete": "Smazat",
- "label.delete-report": "Delete report",
- "label.delete-team": "Delete team",
- "label.delete-user": "Delete user",
+ "label.delete-report": "Smazat hlášení",
+ "label.delete-team": "Smazat tým",
+ "label.delete-user": "Smazat uživatele",
"label.delete-website": "Smazat web",
- "label.description": "Description",
+ "label.description": "Popis",
"label.desktop": "Stolní počítač",
- "label.details": "Details",
- "label.device": "Device",
+ "label.details": "Detaily",
+ "label.device": "Zařízení",
"label.devices": "Zařízení",
"label.dismiss": "Odejít",
- "label.does-not-contain": "Does not contain",
+ "label.does-not-contain": "Neobsahuje",
"label.domain": "Doména",
"label.dropoff": "Dropoff",
"label.edit": "Upravit",
- "label.edit-dashboard": "Edit dashboard",
- "label.edit-member": "Edit member",
+ "label.edit-dashboard": "Upravit dashboard",
+ "label.edit-member": "Upravit člena",
"label.enable-share-url": "Povolit sdílení URL",
"label.end-step": "End Step",
- "label.entry": "Entry URL",
- "label.event": "Event",
+ "label.entry": "Vstupní URL",
+ "label.event": "Událost",
"label.event-data": "Event data",
"label.events": "Události",
"label.exit": "Exit URL",
"label.false": "False",
- "label.field": "Field",
+ "label.field": "Pole",
"label.fields": "Fields",
- "label.filter": "Filter",
+ "label.filter": "Filtr",
"label.filter-combined": "Kombinace",
"label.filter-raw": "Nezpracované",
- "label.filters": "Filters",
+ "label.filters": "Filtry",
"label.first-seen": "First seen",
"label.funnel": "Funnel",
"label.funnel-description": "Understand the conversion and drop-off rate of users.",
- "label.goal": "Goal",
- "label.goals": "Goals",
+ "label.goal": "Cíl",
+ "label.goals": "Cíle",
"label.goals-description": "Track your goals for pageviews and events.",
"label.greater-than": "Greater than",
"label.greater-than-equals": "Greater than or equals",
@@ -98,44 +98,44 @@
"label.join-team": "Join team",
"label.journey": "Journey",
"label.journey-description": "Understand how users navigate through your website.",
- "label.language": "Language",
- "label.languages": "Languages",
+ "label.language": "Jazyk",
+ "label.languages": "Jazyky",
"label.laptop": "Přenosný počítač",
"label.last-days": "Posledních {x} dnů",
"label.last-hours": "Posledních {x} hodin",
- "label.last-months": "Last {x} months",
+ "label.last-months": "Posledních {x} měsíců",
"label.last-seen": "Last seen",
- "label.leave": "Leave",
- "label.leave-team": "Leave team",
+ "label.leave": "Opustit",
+ "label.leave-team": "Opustit tým",
"label.less-than": "Less than",
"label.less-than-equals": "Less than or equals",
"label.login": "Přihlásit",
"label.logout": "Odhlásit",
- "label.manage": "Manage",
- "label.manager": "Manager",
+ "label.manage": "Spravovat",
+ "label.manager": "Správce",
"label.max": "Max",
- "label.member": "Member",
- "label.members": "Members",
+ "label.member": "Člen",
+ "label.members": "Členové",
"label.min": "Min",
"label.mobile": "Mobilní telefon",
"label.more": "Více",
- "label.my-account": "My account",
- "label.my-websites": "My websites",
+ "label.my-account": "Můj účet",
+ "label.my-websites": "Mé weby",
"label.name": "Jméno",
"label.new-password": "Nové heslo",
"label.none": "None",
"label.number-of-records": "{x} {x, plural, one {record} other {records}}",
"label.ok": "OK",
"label.os": "OS",
- "label.overview": "Overview",
- "label.owner": "Owner",
+ "label.overview": "Přehled",
+ "label.owner": "Vlastník",
"label.page-of": "Page {current} of {total}",
"label.page-views": "Zobrazení stránek",
- "label.pageTitle": "Page title",
+ "label.pageTitle": "Název stránky",
"label.pages": "Stránky",
"label.password": "Heslo",
- "label.path": "Path",
- "label.paths": "Paths",
+ "label.path": "Cesta",
+ "label.paths": "Cesty",
"label.powered-by": "Běží na {name}",
"label.previous": "Previous",
"label.previous-period": "Previous period",
@@ -228,13 +228,13 @@
"label.views": "Zobrazení",
"label.views-per-visit": "Views per visit",
"label.visit-duration": "Průměrný čas návštěvy",
- "label.visitors": "Návštěvy",
- "label.visits": "Visits",
+ "label.visitors": "Návštěvníci",
+ "label.visits": "Návštěvy",
"label.website": "Website",
"label.website-id": "Website ID",
"label.websites": "Weby",
- "label.window": "Window",
- "label.yesterday": "Yesterday",
+ "label.window": "Okno",
+ "label.yesterday": "Včera",
"message.action-confirmation": "Type {confirmation} in the box below to confirm.",
"message.active-users": "{x} aktuálně {x, plural, one {návštěvník} other {návštěvníci}}",
"message.collected-data": "Collected data",
diff --git a/src/lang/de-CH.json b/src/lang/de-CH.json
index aa57f90c..e99ecaca 100644
--- a/src/lang/de-CH.json
+++ b/src/lang/de-CH.json
@@ -2,278 +2,278 @@
"label.access-code": "Zuegangscode",
"label.actions": "Aktione",
"label.activity": "Aktivitätsverlauf",
- "label.add": "Add",
- "label.add-description": "Add description",
- "label.add-member": "Add member",
- "label.add-step": "Add step",
+ "label.add": "hinzuefüege",
+ "label.add-description": "Beschriibig hinzuefüege",
+ "label.add-member": "Mitglied hinzuefüege",
+ "label.add-step": "Schritt hinzuefüege",
"label.add-website": "Websiite hinzuefüege",
"label.admin": "Administrator",
- "label.after": "After",
+ "label.after": "Nach",
"label.all": "Alli",
- "label.all-time": "Gesamte Zitruum",
+ "label.all-time": "Gsamte Zitruum",
"label.analytics": "Analytics",
- "label.average": "Average",
+ "label.average": "Durchschnitt",
"label.back": "Zrugg",
- "label.before": "Before",
+ "label.before": "Vor",
"label.bounce-rate": "Absprungsrate",
- "label.breakdown": "Breakdown",
+ "label.breakdown": "Uufschlüsselig",
"label.browser": "Browser",
"label.browsers": "Browser",
"label.cancel": "Abbreche",
"label.change-password": "Passwort ändere",
"label.cities": "Städt",
- "label.city": "City",
+ "label.city": "Stadt",
"label.clear-all": "Alles lösche",
- "label.compare": "Compare",
+ "label.compare": "Vergliiche",
"label.confirm": "Bestätige",
"label.confirm-password": "Passwort widerhole",
- "label.contains": "Contains",
+ "label.contains": "Enthaltet",
"label.continue": "Wiiter",
- "label.count": "Count",
+ "label.count": "Azahl",
"label.countries": "Länder",
- "label.country": "Country",
- "label.create": "Create",
- "label.create-report": "Create report",
+ "label.country": "Land",
+ "label.create": "Erstelle",
+ "label.create-report": "Bricht erstelle",
"label.create-team": "Team erstelle",
"label.create-user": "Benutzer erstelle",
"label.created": "Erstellt",
"label.created-by": "Created By",
- "label.current": "Current",
- "label.current-password": "Jetzigs Passwort",
+ "label.current": "Aktuell",
+ "label.current-password": "Aktuells Passwort",
"label.custom-range": "Benutzerdefinierte Bereich",
"label.dashboard": "Übersicht",
"label.data": "Datä",
- "label.date": "Date",
+ "label.date": "Datum",
"label.date-range": "Datumsbereich",
- "label.day": "Day",
- "label.default-date-range": "Vorigstellte Datumsbereich",
+ "label.day": "Tag",
+ "label.default-date-range": "Voriigstellte Datumsbereich",
"label.delete": "Lösche",
- "label.delete-report": "Delete report",
+ "label.delete-report": "Bricht lösche",
"label.delete-team": "Team lösche",
"label.delete-user": "Benutzer lösche",
"label.delete-website": "Websiite lösche",
- "label.description": "Description",
+ "label.description": "Beschriibig",
"label.desktop": "Desktop",
"label.details": "Details",
- "label.device": "Device",
+ "label.device": "Grät",
"label.devices": "Grät",
- "label.dismiss": "Verwerfe",
- "label.does-not-contain": "Does not contain",
+ "label.dismiss": "Verwärfe",
+ "label.does-not-contain": "Enthaltet nid",
"label.domain": "Domain",
- "label.dropoff": "Dropoff",
+ "label.dropoff": "Absprung",
"label.edit": "Bearbeite",
"label.edit-dashboard": "Dashboard bearbeite",
- "label.edit-member": "Edit member",
+ "label.edit-member": "Mitglied bearbeite",
"label.enable-share-url": "Freigab-URL aktiviere",
- "label.end-step": "End Step",
- "label.entry": "Entry URL",
- "label.event": "Event",
- "label.event-data": "Event data",
+ "label.end-step": "Schlussschritt",
+ "label.entry": "Iigangs URL",
+ "label.event": "Ereigniss",
+ "label.event-data": "Ereigniss Date",
"label.events": "Ereigniss",
- "label.exit": "Exit URL",
- "label.false": "False",
- "label.field": "Field",
- "label.fields": "Fields",
+ "label.exit": "Uusgangs URL",
+ "label.false": "Falsch",
+ "label.field": "Fäld",
+ "label.fields": "Fälder",
"label.filter": "Filter",
"label.filter-combined": "Kombiniert",
"label.filter-raw": "Rohdate",
"label.filters": "Filters",
- "label.first-seen": "First seen",
- "label.funnel": "Funnel",
- "label.funnel-description": "Understand the conversion and drop-off rate of users.",
- "label.goal": "Goal",
- "label.goals": "Goals",
- "label.goals-description": "Track your goals for pageviews and events.",
- "label.greater-than": "Greater than",
- "label.greater-than-equals": "Greater than or equals",
+ "label.first-seen": "Erstmal gse",
+ "label.funnel": "Tunnel",
+ "label.funnel-description": "Verstönd Sie d Konversions- und Abspruungsrate vo Nutzer.",
+ "label.goal": "Ziel",
+ "label.goals": "Ziele",
+ "label.goals-description": "verfolged Sie Ihri Ziel für Siitenufrüef und Ereigniss.",
+ "label.greater-than": "Grösser als",
+ "label.greater-than-equals": "Grösser oder gliich",
"label.host": "Host",
"label.hosts": "Hosts",
- "label.insights": "Insights",
- "label.insights-description": "Dive deeper into your data by using segments and filters.",
- "label.is": "Is",
- "label.is-not": "Is not",
- "label.is-not-set": "Is not set",
- "label.is-set": "Is set",
+ "label.insights": "Iiblick",
+ "label.insights-description": "Vertüfed Sie sich i Ihri Date, mit Hilf vo Segment und Filter.",
+ "label.is": "Isch",
+ "label.is-not": "Isch nid",
+ "label.is-not-set": "Isch ned gsetzt",
+ "label.is-set": "Isch gsetzt",
"label.join": "Biträte",
"label.join-team": "Team biträte",
- "label.journey": "Journey",
- "label.journey-description": "Understand how users navigate through your website.",
+ "label.journey": "Reis",
+ "label.journey-description": "Verstönd Sie, wie Nutzer dur Ihri Website navigiered.",
"label.language": "Sprach",
"label.languages": "Sprache",
"label.laptop": "Laptop",
"label.last-days": "Letzti {x} Täg",
"label.last-hours": "Letzti {x} Stunde",
- "label.last-months": "Last {x} months",
- "label.last-seen": "Last seen",
+ "label.last-months": "Letzti {x} Mönet",
+ "label.last-seen": "Zletzt gse",
"label.leave": "Verlah",
"label.leave-team": "Team verlah",
- "label.less-than": "Less than",
- "label.less-than-equals": "Less than or equals",
- "label.login": "Aamelde",
- "label.logout": "Abmelde",
- "label.manage": "Manage",
+ "label.less-than": "Kliiner als",
+ "label.less-than-equals": "Kliiner oder gliich",
+ "label.login": "Aamälde",
+ "label.logout": "Abmälde",
+ "label.manage": "Verwalte",
"label.manager": "Manager",
"label.max": "Max",
- "label.member": "Member",
+ "label.member": "Mitglied",
"label.members": "Mitglieder",
"label.min": "Min",
- "label.mobile": "Handy",
+ "label.mobile": "Händy",
"label.more": "Meh",
- "label.my-account": "My account",
- "label.my-websites": "My websites",
+ "label.my-account": "Min Account",
+ "label.my-websites": "Mini Websiite",
"label.name": "Name",
"label.new-password": "Neus Passwort",
"label.none": "Keis",
"label.number-of-records": "{x} {x, plural, one {record} other {records}}",
"label.ok": "OK",
"label.os": "OS",
- "label.overview": "Overview",
+ "label.overview": "Übersicht",
"label.owner": "Bsitzer",
- "label.page-of": "Page {current} of {total}",
+ "label.page-of": "Siite {current} vo {total}",
"label.page-views": "Siitenufrüef",
- "label.pageTitle": "Page title",
+ "label.pageTitle": "Siitetitel",
"label.pages": "Siite",
"label.password": "Passwort",
- "label.path": "Path",
- "label.paths": "Paths",
- "label.powered-by": "Betribe dur {name}",
- "label.previous": "Previous",
- "label.previous-period": "Previous period",
- "label.previous-year": "Previous year",
+ "label.path": "Pfad",
+ "label.paths": "Pfade",
+ "label.powered-by": "Betriibe dur {name}",
+ "label.previous": "Vorherig",
+ "label.previous-period": "Vorherigi Periode",
+ "label.previous-year": "Vorherigs Jahr",
"label.profile": "Profil",
"label.properties": "Properties",
"label.property": "Property",
"label.queries": "Abfrage",
- "label.query": "Query",
+ "label.query": "Abfrag",
"label.query-parameters": "Abfragparameter",
"label.realtime": "Echtzit",
- "label.referrer": "Referrer",
- "label.referrers": "Referrer",
+ "label.referrer": "Verwiiser",
+ "label.referrers": "Verwiisendi",
"label.refresh": "Aktualisiere",
"label.regenerate": "Erneuere",
"label.region": "Region",
"label.regions": "Regionä",
"label.remove": "Entferne",
- "label.remove-member": "Remove member",
- "label.reports": "Reports",
+ "label.remove-member": "Mitglied entferne",
+ "label.reports": "Brichte",
"label.required": "Erforderlich",
"label.reset": "Zruggsetze",
"label.reset-website": "Statistik zruggsetze",
"label.retention": "Retention",
- "label.retention-description": "Measure your website stickiness by tracking how often users return.",
- "label.revenue": "Revenue",
- "label.revenue-description": "Look into your revenue across time.",
- "label.revenue-property": "Revenue Property",
+ "label.retention-description": "Mässed Sie d Verwiilduur vo Ihrere Website, indem Sie verfolged wie oft ihri Nutzer zruggkehred.",
+ "label.revenue": "Umsatz",
+ "label.revenue-description": "Lueged Sie sich Ihre Umsatz im Lauf vor Ziit a.",
+ "label.revenue-property": "Umsatzeigenschafte",
"label.role": "Rollä",
- "label.run-query": "Run query",
+ "label.run-query": "Abfrag starte",
"label.save": "Speichere",
"label.screens": "Bildschirmuflösige",
- "label.search": "Search",
- "label.select": "Select",
- "label.select-date": "Select date",
- "label.select-role": "Select role",
+ "label.search": "Sueche",
+ "label.select": "Auswähle",
+ "label.select-date": "Datä uuswähle",
+ "label.select-role": "Rollä uuswähle",
"label.select-website": "Websiite uuswähle",
- "label.session": "Session",
- "label.sessions": "Sessions",
+ "label.session": "Sitzig",
+ "label.sessions": "Sitzige",
"label.settings": "Istellige",
"label.share-url": "Freigab-URL",
"label.single-day": "Ein Tag",
- "label.start-step": "Start Step",
- "label.steps": "Steps",
- "label.sum": "Sum",
+ "label.start-step": "Startschritt",
+ "label.steps": "Schritt",
+ "label.sum": "Summe",
"label.tablet": "Tablet",
"label.team": "Team",
"label.team-id": "Team ID",
- "label.team-manager": "Team manager",
+ "label.team-manager": "Team Manager",
"label.team-member": "Team Mitglied",
- "label.team-name": "Team name",
+ "label.team-name": "Team Name",
"label.team-owner": "Team Bsitzer",
- "label.team-view-only": "Team view only",
- "label.team-websites": "Team websites",
+ "label.team-view-only": "Nur für Teammitglieder sichtbar",
+ "label.team-websites": "Team Websiite",
"label.teams": "Teams",
"label.theme": "Thema",
- "label.this-month": "De Monet",
- "label.this-week": "Die Wuche",
- "label.this-year": "Das Jahr",
+ "label.this-month": "Dä Monet",
+ "label.this-week": "Diä Wuuche",
+ "label.this-year": "Das Johr",
"label.timezone": "Ziitzone",
"label.title": "Titel",
"label.today": "Hüt",
- "label.toggle-charts": "Schaubilder umschalte",
+ "label.toggle-charts": "Charts umschalte",
"label.total": "Total",
- "label.total-records": "Total records",
+ "label.total-records": "Gsamti Datesätz",
"label.tracking-code": "Tracking Code",
- "label.transactions": "Transactions",
- "label.transfer": "Transfer",
- "label.transfer-website": "Transfer website",
- "label.true": "True",
- "label.type": "Type",
- "label.unique": "Unique",
- "label.unique-visitors": "Eidütigi Bsuecher",
- "label.uniqueCustomers": "Unique Customers",
+ "label.transactions": "Transaktione",
+ "label.transfer": "Transferiere",
+ "label.transfer-website": "Websiite transferiere",
+ "label.true": "Wahr",
+ "label.type": "Typ",
+ "label.unique": "Einzigartigi",
+ "label.unique-visitors": "Einzigartigi Bsuecher",
+ "label.uniqueCustomers": "Einzigartigi Kunde",
"label.unknown": "Unbekannt",
- "label.untitled": "Untitled",
+ "label.untitled": "Unbennant",
"label.update": "Update",
"label.url": "URL",
"label.urls": "URLs",
"label.user": "Benutzer",
- "label.user-property": "User Property",
+ "label.user-property": "Benutzereigeschafte",
"label.username": "Benutzername",
"label.users": "Benutzer",
"label.utm": "UTM",
- "label.utm-description": "Track your campaigns through UTM parameters.",
- "label.value": "Value",
+ "label.utm-description": "Tracked Sie Ihri Kampagnen mit UTM Parameters.",
+ "label.value": "Wärt",
"label.view": "Azeige",
"label.view-details": "Details azeige",
- "label.view-only": "View only",
+ "label.view-only": "Nume aluege",
"label.views": "Ufrüef",
- "label.views-per-visit": "Views per visit",
+ "label.views-per-visit": "Ufrüef pro Bsuech",
"label.visit-duration": "Durchschn. Bsuechsziit",
"label.visitors": "Bsuecher",
- "label.visits": "Visits",
+ "label.visits": "Bsüech",
"label.website": "Website",
"label.website-id": "Websiite ID",
"label.websites": "Websiite",
- "label.window": "Window",
+ "label.window": "Fenster",
"label.yesterday": "Gester",
- "message.action-confirmation": "Type {confirmation} in the box below to confirm.",
+ "message.action-confirmation": "Typed Sie {confirmation} is Feld underhalb um z bestätige.",
"message.active-users": "{x} {x, plural, one {aktive Bsuecher} other {aktivi Bsuecher}}",
- "message.collected-data": "Collected data",
+ "message.collected-data": "Gsammleti Date",
"message.confirm-delete": "Sind Sie sich sicher, {target} zlösche?",
"message.confirm-leave": "Sind Sie sich sicher, {target} zverlah?",
- "message.confirm-remove": "Are you sure you want to remove {target}?",
- "message.confirm-reset": "Sind Sie sicher, dass Sie dStatistike vo {target} zruggsetze wend?",
- "message.delete-team-warning": "Deleting a team will also delete all team websites.",
- "message.delete-website-warning": "Alli dezueghörige Date werdet ebefalls glöscht.",
- "message.error": "Es isch en Fehler uftrete.",
+ "message.confirm-remove": "Sind Sie sich sicher, dass Sie {target} wänd entferne?",
+ "message.confirm-reset": "Sind Sie sicher, dass Sie d Statistike vo {target} zruggsetze wänd?",
+ "message.delete-team-warning": "Es Team lösche dued ebefalls alli team Websiite lösche.",
+ "message.delete-website-warning": "Alli dezueghörige Date werded ebefalls glöscht.",
+ "message.error": "Es isch en Fehler ufträte.",
"message.event-log": "{event} uf {url}",
"message.go-to-settings": "Zu de Istellige",
- "message.incorrect-username-password": "Falschs Passwort oder Benutzername.",
+ "message.incorrect-username-password": "Falsches Passwort oder Benutzername.",
"message.invalid-domain": "Ungültigi Domain",
"message.min-password-length": "Miminamli längi vo {n} Zeiche",
- "message.new-version-available": "A new version of Umami {version} is available!",
+ "message.new-version-available": "Es isch en neue Version vo Umami {version} verfügbar!",
"message.no-data-available": "Kei Date vorhande.",
- "message.no-event-data": "No event data is available.",
+ "message.no-event-data": "Es sind kei Event Date verfügbar.",
"message.no-match-password": "Passwörter stimmed ned überi",
- "message.no-results-found": "No results were found.",
+ "message.no-results-found": "Kei Ergäbnis gfunde.",
"message.no-team-websites": "Dem Team sind kei Websiite zuegordnet.",
"message.no-teams": "Bisher sind no kei Teams erstellt worde.",
"message.no-users": "Da gits kei Benutzer",
"message.no-websites-configured": "Es isch kei Websiite vorhande.",
"message.page-not-found": "Siite ned gfunde.",
- "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.",
+ "message.reset-website": "Um die Websiite zruggzsetze, typed Sie {confirmation} is Feld unde dran.",
"message.reset-website-warning": "Alli Date für die Websiite werdet glöscht, nur de Tracking Code blibt bestah.",
"message.saved": "Erfolgrich gspeichert.",
"message.share-url": "Ihri Websiitestatistik isch under de folgende URL öffentlich zuegänglich:",
- "message.team-already-member": "Sie sind bereits es Mitglied vo dem Team.",
+ "message.team-already-member": "Sie sind bereits es Mitglied vo däm Team.",
"message.team-not-found": "Team nöd gfunde.",
- "message.team-websites-info": "Websiite chönd vo jedem im Team agluegt werde",
+ "message.team-websites-info": "Websiite chöi vo jedem im Team agluegt werde",
"message.tracking-code": "Tracking Code",
- "message.transfer-team-website-to-user": "Transfer this website to your account?",
- "message.transfer-user-website-to-team": "Select the team to transfer this website to.",
- "message.transfer-website": "Transfer website ownership to your account or another team.",
- "message.triggered-event": "Triggered event",
- "message.user-deleted": "Benutzer glöscht.",
- "message.viewed-page": "Viewed page",
- "message.visitor-log": "Bsuecher us {country} benutzt {browser} uf {os} {device}",
- "message.visitors-dropped-off": "Visitors dropped off"
-}
+ "message.transfer-team-website-to-user": "Websiite uf zu Ihrem Account transferiere?",
+ "message.transfer-user-website-to-team": "Wähled Sie s Team zum däm Websiite transferiert werde söll.",
+ "message.transfer-website": "Übertraged Sie d Websiite Eigetümerrecht uf Ihre Account oder uf es anders Team",
+ "message.triggered-event": "Usglösts Ereigniss",
+ "message.user-deleted": "Bnutzer glöscht.",
+ "message.viewed-page": "Siite agluegt",
+ "message.visitor-log": "Bsuecher us {country} nutzt {browser} uf {os} {device}",
+ "message.visitors-dropped-off": "Bsuercher verlore"
+}
\ No newline at end of file
diff --git a/src/lang/de-DE.json b/src/lang/de-DE.json
index dfbb9a47..36090a84 100644
--- a/src/lang/de-DE.json
+++ b/src/lang/de-DE.json
@@ -67,8 +67,8 @@
"label.enable-share-url": "Freigabe-URL aktivieren",
"label.end-step": "Schlussschritt",
"label.entry": "Eingangs-URL",
- "label.event": "Ereigniss",
- "label.event-data": "Ereignissdaten",
+ "label.event": "Ereignis",
+ "label.event-data": "Ereignisdaten",
"label.events": "Ereignisse",
"label.exit": "Ausgangs-URL",
"label.false": "Falsch",
@@ -271,7 +271,7 @@
"message.transfer-team-website-to-user": "Diese Website zu Ihrem Account transferieren?",
"message.transfer-user-website-to-team": "Wählen Sie ein Team aus, zu dem die Website transferiert werden soll.",
"message.transfer-website": "Übertragen Sie die Eigentümerrechte zu Ihrem Account oder einem anderen Team.",
- "message.triggered-event": "Ausgelöstes Ereigniss",
+ "message.triggered-event": "Ereignis ausgelöst",
"message.user-deleted": "Benutzer gelöscht.",
"message.viewed-page": "Seite besucht",
"message.visitor-log": "Besucher aus {country} benutzt {browser} auf {os} {device}",
diff --git a/src/lang/fr-FR.json b/src/lang/fr-FR.json
index e1c9befe..8e390dc5 100644
--- a/src/lang/fr-FR.json
+++ b/src/lang/fr-FR.json
@@ -66,7 +66,7 @@
"label.edit-member": "Modifier le membre",
"label.enable-share-url": "Activer l'URL de partage",
"label.end-step": "End Step",
- "label.entry": "Entry URL",
+ "label.entry": "URL d'entrée",
"label.event": "Évènement",
"label.event-data": "Données d'évènements",
"label.events": "Évènements",
@@ -78,12 +78,12 @@
"label.filter-combined": "Combiné",
"label.filter-raw": "Brut",
"label.filters": "Filtres",
- "label.first-seen": "First seen",
+ "label.first-seen": "Vu pour la première fois",
"label.funnel": "Entonnoir",
"label.funnel-description": "Suivi des conversions et des taux d'abandons.",
"label.goal": "Goal",
"label.goals": "Goals",
- "label.goals-description": "Track your goals for pageviews and events.",
+ "label.goals-description": "Suivez vos objectifs en matière de pages vues et d'événements.",
"label.greater-than": "Supérieur à",
"label.greater-than-equals": "Supérieur ou égal à",
"label.host": "Host",
@@ -97,7 +97,7 @@
"label.join": "Rejoindre",
"label.join-team": "Rejoindre une équipe",
"label.journey": "Journey",
- "label.journey-description": "Understand how users navigate through your website.",
+ "label.journey-description": "Comprendre comment les utilisateurs naviguent sur votre site web.",
"label.language": "Langue",
"label.languages": "Langues",
"label.laptop": "Portable",
@@ -137,12 +137,12 @@
"label.path": "Path",
"label.paths": "Paths",
"label.powered-by": "Propulsé par {name}",
- "label.previous": "Previous",
- "label.previous-period": "Previous period",
- "label.previous-year": "Previous year",
+ "label.previous": "Précédent",
+ "label.previous-period": "Période précédente",
+ "label.previous-year": "Année précédente",
"label.profile": "Profil",
- "label.properties": "Properties",
- "label.property": "Property",
+ "label.properties": "Propriétés",
+ "label.property": "Propriété",
"label.queries": "Requêtes",
"label.query": "Requête",
"label.query-parameters": "Paramètres de requête",
@@ -162,14 +162,14 @@
"label.retention": "Rétention",
"label.retention-description": "Mesure de l'attractivité du site en visualisant les taux de visiteurs qui reviennent.",
"label.revenue": "Revenue",
- "label.revenue-description": "Look into your revenue across time.",
- "label.revenue-property": "Revenue Property",
+ "label.revenue-description": "Examinez vos revenus au fil du temps.",
+ "label.revenue-property": "Propriétés des revenues",
"label.role": "Rôle",
"label.run-query": "Éxécuter la requête",
"label.save": "Enregistrer",
"label.screens": "Résolutions d'écran",
"label.search": "Rechercher",
- "label.select": "Select",
+ "label.select": "Selectionner",
"label.select-date": "Choisir une période",
"label.select-role": "Choisir un rôle",
"label.select-website": "Choisir un site",
@@ -178,17 +178,17 @@
"label.settings": "Paramètres",
"label.share-url": "URL de partage",
"label.single-day": "Journée",
- "label.start-step": "Start Step",
+ "label.start-step": "Etape de démarrage",
"label.steps": "Étapes",
"label.sum": "Somme",
"label.tablet": "Tablette",
"label.team": "Équipe",
"label.team-id": "ID d'équipe",
- "label.team-manager": "Team manager",
+ "label.team-manager": "Manager de l'équipe",
"label.team-member": "Membre de l'équipe",
"label.team-name": "Nom de l'équipe",
"label.team-owner": "Propriétaire de l'équipe",
- "label.team-view-only": "Team view only",
+ "label.team-view-only": "Vue d'équipe uniquement",
"label.team-websites": "Sites d'équipes",
"label.teams": "Équipes",
"label.theme": "Thème",
@@ -209,14 +209,14 @@
"label.type": "Type",
"label.unique": "Unique",
"label.unique-visitors": "Visiteurs uniques",
- "label.uniqueCustomers": "Unique Customers",
+ "label.uniqueCustomers": "Clients uniques",
"label.unknown": "Inconnu",
"label.untitled": "Sans titre",
"label.update": "Modifier",
"label.url": "URL",
"label.urls": "URLs",
"label.user": "Utilisateur",
- "label.user-property": "User Property",
+ "label.user-property": "Propriétés d'utilisateurs",
"label.username": "Nom d'utilisateur",
"label.users": "Utilisateurs",
"label.utm": "UTM",
diff --git a/src/lang/ko-KR.json b/src/lang/ko-KR.json
index 07494d93..933e2883 100644
--- a/src/lang/ko-KR.json
+++ b/src/lang/ko-KR.json
@@ -160,7 +160,7 @@
"label.reset": "초기화",
"label.reset-website": "웹사이트 초기화",
"label.retention": "리텐션",
- "label.retention-description": "사용자가 얼마나 자주 돌아오는지를 추적하여 웹사이트의 리텐션을 측정하십시오.",
+ "label.retention-description": "사용자가 얼마나 자주 돌아오는지를 추적하여 웹사이트의 리텐션을 측정하세요.",
"label.revenue": "수익",
"label.revenue-description": "시간대별 수익을 살펴보세요.",
"label.revenue-property": "수익 속성",
@@ -220,14 +220,14 @@
"label.username": "사용자 이름",
"label.users": "사용자",
"label.utm": "UTM",
- "label.utm-description": "UTM 매개변수를 통해 캠페인을 추적합니다.",
+ "label.utm-description": "UTM 매개변수를 통해 캠페인을 추적하세요.",
"label.value": "값",
"label.view": "보기",
"label.view-details": "자세히 보기",
"label.view-only": "보기 전용",
"label.views": "조회",
"label.views-per-visit": "방문당 조회",
- "label.visit-duration": "평균 방문 시간",
+ "label.visit-duration": "방문 시간",
"label.visitors": "방문자",
"label.visits": "방문",
"label.website": "웹사이트",
@@ -244,7 +244,7 @@
"message.confirm-reset": "{target}을(를) 초기화하시겠습니까?",
"message.delete-team-warning": "팀을 삭제하면 팀에 등록된 모든 웹사이트도 삭제됩니다.",
"message.delete-website-warning": "관련된 모든 데이터가 삭제됩니다.",
- "message.error": "오류가 발생했습니다.",
+ "message.error": "문제가 발생했습니다.",
"message.event-log": "{event} - {url}",
"message.go-to-settings": "설정으로 이동",
"message.incorrect-username-password": "사용자 이름 또는 비밀번호를 잘못 입력했습니다.",
diff --git a/src/lang/ro-RO.json b/src/lang/ro-RO.json
index f60f8f2b..feb3dd5b 100644
--- a/src/lang/ro-RO.json
+++ b/src/lang/ro-RO.json
@@ -5,8 +5,8 @@
"label.add": "Adaugă",
"label.add-description": "Adaugă descriere",
"label.add-member": "Adaugă membru",
- "label.add-step": "Add step",
- "label.add-website": "Adăugare site web",
+ "label.add-step": "Adaugă pas",
+ "label.add-website": "Adaugă site web",
"label.admin": "Administrator",
"label.after": "După",
"label.all": "Toate",
@@ -24,12 +24,12 @@
"label.cities": "Orașe",
"label.city": "Oraș",
"label.clear-all": "Șterge tot",
- "label.compare": "Compare",
+ "label.compare": "Compară",
"label.confirm": "Confirm",
"label.confirm-password": "Confirmare parolă",
"label.contains": "Conține",
"label.continue": "Continuă",
- "label.count": "Count",
+ "label.count": "Număr",
"label.countries": "Țări",
"label.country": "Țară",
"label.create": "Crează",
@@ -37,21 +37,21 @@
"label.create-team": "Crează echipă",
"label.create-user": "Crează utilizator",
"label.created": "Creat",
- "label.created-by": "Created By",
- "label.current": "Current",
+ "label.created-by": "Creat de",
+ "label.current": "Curent",
"label.current-password": "Parola curentă",
"label.custom-range": "Interval personalizat",
"label.dashboard": "Tablou de bord",
"label.data": "Date",
- "label.date": "Data",
- "label.date-range": "Interval de date",
+ "label.date": "Dată",
+ "label.date-range": "Interval",
"label.day": "Zi",
- "label.default-date-range": "Interval de date implicit",
+ "label.default-date-range": "Interval implicit",
"label.delete": "Șterge",
"label.delete-report": "Șterge raport",
"label.delete-team": "Șterge echipă",
"label.delete-user": "Șterge utilizator",
- "label.delete-website": "Ștergere site web",
+ "label.delete-website": "Șterge site web",
"label.description": "Descriere",
"label.desktop": "Desktop",
"label.details": "Detalii",
@@ -65,12 +65,12 @@
"label.edit-dashboard": "Editare tablou de bord",
"label.edit-member": "Editare membru",
"label.enable-share-url": "Activare adresă URL de distribuire",
- "label.end-step": "End Step",
- "label.entry": "Entry URL",
+ "label.end-step": "Pas final",
+ "label.entry": "URL de intrare",
"label.event": "Eveniment",
"label.event-data": "Date despre eveniment",
"label.events": "Evenimente",
- "label.exit": "Exit URL",
+ "label.exit": "URL de ieșire",
"label.false": "Fals",
"label.field": "Câmp",
"label.fields": "Câmpuri",
@@ -78,12 +78,12 @@
"label.filter-combined": "Combinat",
"label.filter-raw": "Brut",
"label.filters": "Filtre",
- "label.first-seen": "First seen",
+ "label.first-seen": "Văzut pentru prima dată",
"label.funnel": "Parcursul utilizatorului",
"label.funnel-description": "Înțelege rata de conversie și rata de abandon a utilizatorilor.",
- "label.goal": "Goal",
- "label.goals": "Goals",
- "label.goals-description": "Track your goals for pageviews and events.",
+ "label.goal": "Obiectiv",
+ "label.goals": "Obiective",
+ "label.goals-description": "Urmărește obiectivele de vizualizări și evenimente.",
"label.greater-than": "Mai mare decât",
"label.greater-than-equals": "Mai mare sau egal cu",
"label.host": "Host",
@@ -96,15 +96,15 @@
"label.is-set": "Este setat",
"label.join": "Alătură-te",
"label.join-team": "Alătură-te echipei",
- "label.journey": "Journey",
- "label.journey-description": "Understand how users navigate through your website.",
+ "label.journey": "Traseu",
+ "label.journey-description": "Înțelege cum navighează vizitatorii prin website.",
"label.language": "Limbă",
"label.languages": "Limbi",
"label.laptop": "Laptop",
"label.last-days": "Ultimele {x} zile",
"label.last-hours": "Ultimele {x} ore",
- "label.last-months": "Last {x} months",
- "label.last-seen": "Last seen",
+ "label.last-months": "Ultimele {x} luni",
+ "label.last-seen": "Văzut ultima dată",
"label.leave": "Părăsește",
"label.leave-team": "Părăsește echipa",
"label.less-than": "Mai puțin decât",
@@ -134,15 +134,15 @@
"label.pageTitle": "Titlul paginii",
"label.pages": "Pagini",
"label.password": "Parolă",
- "label.path": "Path",
- "label.paths": "Paths",
+ "label.path": "Rută",
+ "label.paths": "Rute",
"label.powered-by": "Cu sprijinul {name}",
- "label.previous": "Previous",
- "label.previous-period": "Previous period",
- "label.previous-year": "Previous year",
+ "label.previous": "Anterior",
+ "label.previous-period": "Perioda anterioară",
+ "label.previous-year": "Anul anterior",
"label.profile": "Profil",
- "label.properties": "Properties",
- "label.property": "Property",
+ "label.properties": "Proprietăți",
+ "label.property": "Proprietate",
"label.queries": "Interogări",
"label.query": "Interogare",
"label.query-parameters": "Parametri de interogare",
@@ -161,8 +161,8 @@
"label.reset-website": "Resetează statisticile pentru site",
"label.retention": "Retenție",
"label.retention-description": "Măsoară atractivitatea site-ului tău prin urmărirea frecvenței cu care utilizatorii se întorc.",
- "label.revenue": "Revenue",
- "label.revenue-description": "Look into your revenue across time.",
+ "label.revenue": "Venit",
+ "label.revenue-description": "Urmărește venitul în timp.",
"label.revenue-property": "Revenue Property",
"label.role": "Rol",
"label.run-query": "Execută interogarea",
@@ -173,18 +173,18 @@
"label.select-date": "Selectează data",
"label.select-role": "Selectează rolul",
"label.select-website": "Selectează website",
- "label.session": "Session",
+ "label.session": "Sesiune",
"label.sessions": "Sesiuni",
"label.settings": "Setări",
"label.share-url": "Partajare URL",
"label.single-day": "O singură zi",
- "label.start-step": "Start Step",
- "label.steps": "Steps",
+ "label.start-step": "Pas de început",
+ "label.steps": "Pași",
"label.sum": "Sumă",
"label.tablet": "Tabletă",
"label.team": "Echipă",
- "label.team-id": "ID Echipa",
- "label.team-manager": "Team manager",
+ "label.team-id": "ID Echipă",
+ "label.team-manager": "Manager echipă",
"label.team-member": "Membru echipă",
"label.team-name": "Nume echipă",
"label.team-owner": "Titular echipă",
@@ -202,34 +202,34 @@
"label.total": "Total",
"label.total-records": "Total înregistrări",
"label.tracking-code": "Cod de urmărire",
- "label.transactions": "Transactions",
+ "label.transactions": "Tranzacții",
"label.transfer": "Transfer",
"label.transfer-website": "Transfer website",
"label.true": "Adevărat",
"label.type": "Tip",
"label.unique": "Unici",
"label.unique-visitors": "Vizitatori unici",
- "label.uniqueCustomers": "Unique Customers",
+ "label.uniqueCustomers": "Clienți unici",
"label.unknown": "Necunoscut",
"label.untitled": "Fără titlu",
"label.update": "Update",
"label.url": "URL",
"label.urls": "URLs",
"label.user": "Utilizator",
- "label.user-property": "User Property",
+ "label.user-property": "Proprietatea utilizatorului",
"label.username": "Nume utilizator",
"label.users": "Utilizatori",
"label.utm": "UTM",
- "label.utm-description": "Track your campaigns through UTM parameters.",
+ "label.utm-description": "Urmărește campaniile tale cu parametri UTM.",
"label.value": "Valoare",
"label.view": "Vizualizare",
"label.view-details": "Vizualizare detalii",
"label.view-only": "Doar vizualizare",
"label.views": "Vizualizări",
- "label.views-per-visit": "Views per visit",
+ "label.views-per-visit": "Vizualizări per vizită",
"label.visit-duration": "Timp mediu de vizitare",
"label.visitors": "Vizitatori",
- "label.visits": "Visits",
+ "label.visits": "Vizite",
"label.website": "Website",
"label.website-id": "ID Website",
"label.websites": "Site-uri web",
@@ -237,7 +237,7 @@
"label.yesterday": "Ieri",
"message.action-confirmation": "Scrie {confirmation} în câmpul de mai jos pentru a confirma.",
"message.active-users": "{x} {x, plural, one {vizitator activ} other {vizitatori activi}}",
- "message.collected-data": "Collected data",
+ "message.collected-data": "Date colectate",
"message.confirm-delete": "Ești sigur că vrei să ștergi {target}?",
"message.confirm-leave": "Ești sigur că vrei să părăsești {target}?",
"message.confirm-remove": "Ești sigur că vrei să ștergi {target}?",
diff --git a/src/lang/ru-RU.json b/src/lang/ru-RU.json
index f483522a..558b411a 100644
--- a/src/lang/ru-RU.json
+++ b/src/lang/ru-RU.json
@@ -2,194 +2,194 @@
"label.access-code": "Код доступа",
"label.actions": "Действия",
"label.activity": "Журнал активности",
- "label.add": "Add",
- "label.add-description": "Add description",
- "label.add-member": "Add member",
- "label.add-step": "Add step",
+ "label.add": "Добавить",
+ "label.add-description": "Добавить описание",
+ "label.add-member": "Добавить участника",
+ "label.add-step": "Добавить шаг",
"label.add-website": "Добавить сайт",
"label.admin": "Администратор",
- "label.after": "After",
+ "label.after": "После",
"label.all": "Все",
"label.all-time": "Все время",
"label.analytics": "Аналитика",
- "label.average": "Average",
+ "label.average": "Средний",
"label.back": "Назад",
- "label.before": "Before",
+ "label.before": "До",
"label.bounce-rate": "Отказы",
- "label.breakdown": "Breakdown",
- "label.browser": "Browser",
+ "label.breakdown": "Авария",
+ "label.browser": "Браузер",
"label.browsers": "Браузеры",
"label.cancel": "Отменить",
"label.change-password": "Изменить пароль",
"label.cities": "Города",
- "label.city": "City",
+ "label.city": "Город",
"label.clear-all": "Очистить все",
- "label.compare": "Compare",
+ "label.compare": "Сравнить",
"label.confirm": "Подтвердить",
"label.confirm-password": "Подтвердить пароль",
- "label.contains": "Contains",
+ "label.contains": "Содержит",
"label.continue": "Продолжить",
- "label.count": "Count",
+ "label.count": "Считать",
"label.countries": "Страны",
- "label.country": "Country",
- "label.create": "Create",
- "label.create-report": "Create report",
+ "label.country": "Страна",
+ "label.create": "Создать",
+ "label.create-report": "Создать отчет",
"label.create-team": "Создать команду",
"label.create-user": "Создать пользователя",
"label.created": "Создано",
- "label.created-by": "Created By",
- "label.current": "Current",
+ "label.created-by": "Создано",
+ "label.current": "Текущий",
"label.current-password": "Текущий пароль",
"label.custom-range": "Другой период",
"label.dashboard": "Информационная панель",
"label.data": "Данные",
- "label.date": "Date",
+ "label.date": "Дата",
"label.date-range": "Диапазон дат",
- "label.day": "Day",
+ "label.day": "День",
"label.default-date-range": "Диапазон дат по-умолчанию",
"label.delete": "Удалить",
- "label.delete-report": "Delete report",
+ "label.delete-report": "Удалить отчет",
"label.delete-team": "Удалить команду",
"label.delete-user": "Удалить пользователя",
"label.delete-website": "Удалить сайт",
- "label.description": "Description",
+ "label.description": "Описание",
"label.desktop": "Настольный компьютер",
"label.details": "Подробности",
- "label.device": "Device",
+ "label.device": "Устройство",
"label.devices": "Устройства",
"label.dismiss": "Отклонить",
- "label.does-not-contain": "Does not contain",
+ "label.does-not-contain": "Не содержит",
"label.domain": "Домен",
- "label.dropoff": "Dropoff",
+ "label.dropoff": "Высадка",
"label.edit": "Изменить",
"label.edit-dashboard": "Редактировать дашборд",
- "label.edit-member": "Edit member",
+ "label.edit-member": "Редактировать участника",
"label.enable-share-url": "Разрешить делиться ссылкой",
- "label.end-step": "End Step",
- "label.entry": "Entry URL",
- "label.event": "Event",
- "label.event-data": "Event data",
+ "label.end-step": "Конечный шаг",
+ "label.entry": "URL-адрес входа",
+ "label.event": "Событие",
+ "label.event-data": "Данные о событии",
"label.events": "События",
- "label.exit": "Exit URL",
- "label.false": "False",
- "label.field": "Field",
- "label.fields": "Fields",
- "label.filter": "Filter",
+ "label.exit": "URL-адрес выхода",
+ "label.false": "Ложь",
+ "label.field": "Поле",
+ "label.fields": "Поля",
+ "label.filter": "Фильтр",
"label.filter-combined": "Объединенные",
"label.filter-raw": "Сырые данные",
- "label.filters": "Filters",
- "label.first-seen": "First seen",
- "label.funnel": "Funnel",
- "label.funnel-description": "Understand the conversion and drop-off rate of users.",
- "label.goal": "Goal",
- "label.goals": "Goals",
- "label.goals-description": "Track your goals for pageviews and events.",
- "label.greater-than": "Greater than",
- "label.greater-than-equals": "Greater than or equals",
+ "label.filters": "Фильтры",
+ "label.first-seen": "Первый вход",
+ "label.funnel": "Воронка",
+ "label.funnel-description": "Изучите коэффициент конверсии и ухода пользователей.",
+ "label.goal": "Цель",
+ "label.goals": "Цели",
+ "label.goals-description": "Отслеживайте свои цели по просмотрам страниц и событиям.",
+ "label.greater-than": "Больше, чем",
+ "label.greater-than-equals": "Больше или равно",
"label.host": "Host",
"label.hosts": "Hosts",
- "label.insights": "Insights",
- "label.insights-description": "Dive deeper into your data by using segments and filters.",
- "label.is": "Is",
- "label.is-not": "Is not",
- "label.is-not-set": "Is not set",
- "label.is-set": "Is set",
+ "label.insights": "Информация",
+ "label.insights-description": "Погрузитесь глубже в свои данные с помощью сегментов и фильтров.",
+ "label.is": "Является",
+ "label.is-not": "Не установлен",
+ "label.is-not-set": "Не установлено",
+ "label.is-set": "Установлен",
"label.join": "Присоединиться",
"label.join-team": "Присоединиться к команде",
"label.journey": "Journey",
- "label.journey-description": "Understand how users navigate through your website.",
+ "label.journey-description": "Поймите, как пользователи перемещаются по вашему сайту.",
"label.language": "Язык",
"label.languages": "Языки",
"label.laptop": "Ноутбук",
"label.last-days": "Последние {x} дней",
"label.last-hours": "Последние {x} часа",
- "label.last-months": "Last {x} months",
- "label.last-seen": "Last seen",
+ "label.last-months": "Последние {x} месяцев",
+ "label.last-seen": "Последний вход",
"label.leave": "Уйти",
"label.leave-team": "Покинуть команду",
- "label.less-than": "Less than",
- "label.less-than-equals": "Less than or equals",
+ "label.less-than": "Меньше, чем",
+ "label.less-than-equals": "Меньше или равно",
"label.login": "Войти",
"label.logout": "Выйти",
- "label.manage": "Manage",
- "label.manager": "Manager",
- "label.max": "Max",
- "label.member": "Member",
+ "label.manage": "Управление",
+ "label.manager": "Менеджер",
+ "label.max": "Максимум",
+ "label.member": "Участник",
"label.members": "Участники",
- "label.min": "Min",
+ "label.min": "Минимум",
"label.mobile": "Смартфон",
"label.more": "Больше",
- "label.my-account": "My account",
- "label.my-websites": "My websites",
+ "label.my-account": "Мой профиль",
+ "label.my-websites": "Мои сайты",
"label.name": "Имя",
"label.new-password": "Новый пароль",
"label.none": "Не указано",
- "label.number-of-records": "{x} {x, plural, one {record} other {records}}",
+ "label.number-of-records": "{x} {x, plural, one {запись} other {записи}}",
"label.ok": "OK",
"label.os": "OS",
- "label.overview": "Overview",
+ "label.overview": "Обзор",
"label.owner": "Владелец",
- "label.page-of": "Page {current} of {total}",
+ "label.page-of": "Страница {current} из {total}",
"label.page-views": "Просмотры страниц",
- "label.pageTitle": "Page title",
+ "label.pageTitle": "Название страницы",
"label.pages": "Страницы",
"label.password": "Пароль",
- "label.path": "Path",
- "label.paths": "Paths",
+ "label.path": "Путь",
+ "label.paths": "Пути",
"label.powered-by": "На движке {name}",
- "label.previous": "Previous",
- "label.previous-period": "Previous period",
- "label.previous-year": "Previous year",
+ "label.previous": "Предыдущий",
+ "label.previous-period": "Предыдущий период",
+ "label.previous-year": "Предыдущий год",
"label.profile": "Профиль",
- "label.properties": "Properties",
- "label.property": "Property",
+ "label.properties": "Свойства",
+ "label.property": "Свойство",
"label.queries": "Запросы",
- "label.query": "Query",
+ "label.query": "Запрос",
"label.query-parameters": "Параметры запроса",
"label.realtime": "Реальное время",
- "label.referrer": "Referrer",
+ "label.referrer": "Реферер",
"label.referrers": "Источники",
"label.refresh": "Обновить",
"label.regenerate": "Обновить",
- "label.region": "Region",
+ "label.region": "Регион",
"label.regions": "Регионы",
"label.remove": "Удалить",
- "label.remove-member": "Remove member",
- "label.reports": "Reports",
+ "label.remove-member": "Удалить участника",
+ "label.reports": "Отчеты",
"label.required": "Обязательное",
"label.reset": "Сбросить",
"label.reset-website": "Сбросить статистику",
- "label.retention": "Retention",
- "label.retention-description": "Measure your website stickiness by tracking how often users return.",
- "label.revenue": "Revenue",
- "label.revenue-description": "Look into your revenue across time.",
- "label.revenue-property": "Revenue Property",
+ "label.retention": "Удержание",
+ "label.retention-description": "Измерьте «прилипаемость» вашего сайта, отслеживая, как часто пользователи возвращаются на него.",
+ "label.revenue": "Выручка",
+ "label.revenue-description": "Изучите свои доходы за определенное время.",
+ "label.revenue-property": "Доходная недвижимость",
"label.role": "Роль",
- "label.run-query": "Run query",
+ "label.run-query": "Выполнить запрос",
"label.save": "Сохранить",
"label.screens": "Экраны",
- "label.search": "Search",
- "label.select": "Select",
- "label.select-date": "Select date",
- "label.select-role": "Select role",
+ "label.search": "Поиск",
+ "label.select": "Выберите",
+ "label.select-date": "Выберите дату",
+ "label.select-role": "Выберите роль",
"label.select-website": "Выбрать сайт",
- "label.session": "Session",
+ "label.session": "Сессия",
"label.sessions": "Сессии",
"label.settings": "Настройки",
"label.share-url": "Поделиться ссылкой",
"label.single-day": "Один день",
- "label.start-step": "Start Step",
- "label.steps": "Steps",
- "label.sum": "Sum",
+ "label.start-step": "Начальный этап",
+ "label.steps": "Шаги",
+ "label.sum": "Сумма",
"label.tablet": "Планшет",
"label.team": "Команда",
"label.team-id": "ID команды",
- "label.team-manager": "Team manager",
+ "label.team-manager": "Менеджер команды",
"label.team-member": "Член команды",
- "label.team-name": "Team name",
+ "label.team-name": "Название команды",
"label.team-owner": "Владелец команды",
- "label.team-view-only": "Team view only",
- "label.team-websites": "Team websites",
+ "label.team-view-only": "Только командный просмотр",
+ "label.team-websites": "Веб-сайты команды",
"label.teams": "Команды",
"label.theme": "Тема",
"label.this-month": "Этот месяц",
@@ -199,62 +199,62 @@
"label.title": "Заголовок",
"label.today": "Сегодня",
"label.toggle-charts": "Показать/скрыть графики",
- "label.total": "Total",
- "label.total-records": "Total records",
+ "label.total": "Всего",
+ "label.total-records": "Всего записей",
"label.tracking-code": "Код отслеживания",
- "label.transactions": "Transactions",
- "label.transfer": "Transfer",
- "label.transfer-website": "Transfer website",
- "label.true": "True",
- "label.type": "Type",
- "label.unique": "Unique",
+ "label.transactions": "Транзакции",
+ "label.transfer": "Передача",
+ "label.transfer-website": "Передать сайт",
+ "label.true": "Правда",
+ "label.type": "Тип",
+ "label.unique": "Уникальный",
"label.unique-visitors": "Уникальные посетители",
- "label.uniqueCustomers": "Unique Customers",
+ "label.uniqueCustomers": "Уникальные клиенты",
"label.unknown": "Неизвестно",
- "label.untitled": "Untitled",
- "label.update": "Update",
+ "label.untitled": "Без названия",
+ "label.update": "Обновление",
"label.url": "URL",
"label.urls": "URLs",
"label.user": "Пользователь",
- "label.user-property": "User Property",
+ "label.user-property": "Собственность пользователя",
"label.username": "Имя пользователя",
"label.users": "Пользователи",
"label.utm": "UTM",
- "label.utm-description": "Track your campaigns through UTM parameters.",
- "label.value": "Value",
+ "label.utm-description": "Отслеживайте свои кампании с помощью UTM-параметров.",
+ "label.value": "Значение",
"label.view": "Просмотреть",
"label.view-details": "Посмотреть детали",
- "label.view-only": "View only",
+ "label.view-only": "Только просмотр",
"label.views": "Просмотры",
- "label.views-per-visit": "Views per visit",
+ "label.views-per-visit": "Просмотров за посещение",
"label.visit-duration": "Среднее время посещения",
"label.visitors": "Посетители",
- "label.visits": "Visits",
- "label.website": "Website",
+ "label.visits": "Посещения",
+ "label.website": "Сайт",
"label.website-id": "ID сайта",
"label.websites": "Сайты",
- "label.window": "Window",
+ "label.window": "Окно",
"label.yesterday": "Вчера",
- "message.action-confirmation": "Type {confirmation} in the box below to confirm.",
+ "message.action-confirmation": "Введите {confirmation} в поле ниже, чтобы подтвердить.",
"message.active-users": "{x} текущих посетителей",
- "message.collected-data": "Collected data",
+ "message.collected-data": "Собранные данные",
"message.confirm-delete": "Вы уверены, что хотите удалить {target}?",
"message.confirm-leave": "Вы уверены, что хотите уйти {target}?",
- "message.confirm-remove": "Are you sure you want to remove {target}?",
+ "message.confirm-remove": "Вы уверены, что хотите удалить {target}?",
"message.confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?",
- "message.delete-team-warning": "Deleting a team will also delete all team websites.",
+ "message.delete-team-warning": "При удалении команды будут удалены и все ее веб-сайты.",
"message.delete-website-warning": "Все связанные данные будут также удалены.",
"message.error": "Что-то пошло не так.",
- "message.event-log": "{event} on {url}",
+ "message.event-log": "{event} на {url}",
"message.go-to-settings": "Перейти к настройкам",
"message.incorrect-username-password": "Неверное имя пользователя/пароль.",
"message.invalid-domain": "Некорректный домен",
"message.min-password-length": "Минимальная длина {n} символов",
- "message.new-version-available": "A new version of Umami {version} is available!",
+ "message.new-version-available": "Вышла новая версия Umami {version}!",
"message.no-data-available": "Нет данных.",
- "message.no-event-data": "No event data is available.",
+ "message.no-event-data": "Данные о событиях отсутствуют.",
"message.no-match-password": "Пароли не совпадают",
- "message.no-results-found": "No results were found.",
+ "message.no-results-found": "Результаты не найдены.",
"message.no-team-websites": "У этой команды нет ни одного сайта.",
"message.no-teams": "Вы не создали ни одной команды.",
"message.no-users": "Нет пользователей.",
@@ -268,12 +268,12 @@
"message.team-not-found": "Команда не найдена.",
"message.team-websites-info": "Сайты могут просматривать все члены команды.",
"message.tracking-code": "Код отслеживания",
- "message.transfer-team-website-to-user": "Transfer this website to your account?",
- "message.transfer-user-website-to-team": "Select the team to transfer this website to.",
- "message.transfer-website": "Transfer website ownership to your account or another team.",
- "message.triggered-event": "Triggered event",
+ "message.transfer-team-website-to-user": "Перенести этот сайт в свой прфоиль?",
+ "message.transfer-user-website-to-team": "Выберите команду, которой нужно передать этот сайт.",
+ "message.transfer-website": "Передайте право владения сайтом своей учетной записи или другой команде.",
+ "message.triggered-event": "Запущенное событие",
"message.user-deleted": "Пользователь удален.",
- "message.viewed-page": "Viewed page",
+ "message.viewed-page": "Просмотренная страница",
"message.visitor-log": "Посетитель из {country} используя {browser} на {os} {device}",
- "message.visitors-dropped-off": "Visitors dropped off"
+ "message.visitors-dropped-off": "Высадка посетителей"
}
diff --git a/src/lib/clickhouse.ts b/src/lib/clickhouse.ts
index 5502b5ba..b588ec84 100644
--- a/src/lib/clickhouse.ts
+++ b/src/lib/clickhouse.ts
@@ -2,9 +2,9 @@ import { ClickHouseClient, createClient } from '@clickhouse/client';
import { formatInTimeZone } from 'date-fns-tz';
import debug from 'debug';
import { CLICKHOUSE } from 'lib/db';
+import { getWebsite } from 'queries/index';
import { DEFAULT_PAGE_SIZE, OPERATORS } from './constants';
import { maxDate } from './date';
-import { fetchWebsite } from './load';
import { filtersToArray } from './params';
import { PageParams, QueryFilters, QueryOptions } from './types';
@@ -132,7 +132,7 @@ function getFilterParams(filters: QueryFilters = {}) {
}
async function parseFilters(websiteId: string, filters: QueryFilters = {}, options?: QueryOptions) {
- const website = await fetchWebsite(websiteId);
+ const website = await getWebsite(websiteId);
return {
filterQuery: getFilterQuery(filters, options),
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
index 5d3a9776..7f8acf88 100644
--- a/src/lib/constants.ts
+++ b/src/lib/constants.ts
@@ -33,7 +33,7 @@ export const FILTER_REFERRERS = 'filter-referrers';
export const FILTER_PAGES = 'filter-pages';
export const UNIT_TYPES = ['year', 'month', 'hour', 'day', 'minute'];
-export const EVENT_COLUMNS = ['url', 'entry', 'exit', 'referrer', 'title', 'query', 'event'];
+export const EVENT_COLUMNS = ['url', 'entry', 'exit', 'referrer', 'title', 'query', 'event', 'tag'];
export const SESSION_COLUMNS = [
'browser',
@@ -63,6 +63,7 @@ export const FILTER_COLUMNS = {
city: 'city',
language: 'language',
event: 'event_name',
+ tag: 'tag',
};
export const COLLECTION_TYPE = {
diff --git a/src/lib/format.ts b/src/lib/format.ts
index a662a9eb..e497464a 100644
--- a/src/lib/format.ts
+++ b/src/lib/format.ts
@@ -47,6 +47,9 @@ export function formatNumber(n: string | number) {
export function formatLongNumber(value: number) {
const n = Number(value);
+ if (n >= 1000000000) {
+ return `${(n / 1000000).toFixed(1)}b`;
+ }
if (n >= 1000000) {
return `${(n / 1000000).toFixed(1)}m`;
}
@@ -78,3 +81,38 @@ export function stringToColor(str: string) {
}
return color;
}
+
+export function formatCurrency(value: number, currency: string, locale = 'en-US') {
+ let formattedValue;
+
+ try {
+ formattedValue = new Intl.NumberFormat(locale, {
+ style: 'currency',
+ currency: currency,
+ });
+ } catch (error) {
+ // Fallback to default currency format if an error occurs
+ formattedValue = new Intl.NumberFormat(locale, {
+ style: 'currency',
+ currency: 'USD',
+ });
+ }
+
+ return formattedValue.format(value);
+}
+
+export function formatLongCurrency(value: number, currency: string, locale = 'en-US') {
+ const n = Number(value);
+
+ if (n >= 1000000000) {
+ return `${formatCurrency(n / 1000000000, currency, locale)}b`;
+ }
+ if (n >= 1000000) {
+ return `${formatCurrency(n / 1000000, currency, locale)}m`;
+ }
+ if (n >= 1000) {
+ return `${formatCurrency(n / 1000, currency, locale)}k`;
+ }
+
+ return formatCurrency(n, currency, locale);
+}
diff --git a/src/lib/types.ts b/src/lib/types.ts
index 7fabbfc8..615882ef 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -179,6 +179,7 @@ export interface QueryFilters {
language?: string;
event?: string;
search?: string;
+ tag?: string;
}
export interface QueryOptions {
diff --git a/src/pages/api/reports/revenue.ts b/src/pages/api/reports/revenue.ts
index ac4dc6b3..d23ce55a 100644
--- a/src/pages/api/reports/revenue.ts
+++ b/src/pages/api/reports/revenue.ts
@@ -5,49 +5,60 @@ import { TimezoneTest, UnitTypeTest } from 'lib/yup';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { getRevenue } from 'queries/analytics/reports/getRevenue';
+import { getRevenueValues } from 'queries/analytics/reports/getRevenueValues';
import * as yup from 'yup';
-export interface RetentionRequestBody {
+export interface RevenueRequestBody {
websiteId: string;
- dateRange: { startDate: string; endDate: string; unit?: string; timezone?: string };
- eventName: string;
- revenueProperty: string;
- userProperty: string;
+ currency?: string;
+ timezone?: string;
+ dateRange: { startDate: string; endDate: string; unit?: string };
}
const schema = {
POST: yup.object().shape({
websiteId: yup.string().uuid().required(),
+ timezone: TimezoneTest,
dateRange: yup
.object()
.shape({
startDate: yup.date().required(),
endDate: yup.date().required(),
unit: UnitTypeTest,
- timezone: TimezoneTest,
})
.required(),
- eventName: yup.string().required(),
- revenueProperty: yup.string().required(),
- userProperty: yup.string(),
}),
};
export default async (
- req: NextApiRequestQueryBody,
+ req: NextApiRequestQueryBody,
res: NextApiResponse,
) => {
await useCors(req, res);
await useAuth(req, res);
await useValidate(schema, req, res);
+ if (req.method === 'GET') {
+ const { websiteId, startDate, endDate } = req.query;
+
+ if (!(await canViewWebsite(req.auth, websiteId))) {
+ return unauthorized(res);
+ }
+
+ const data = await getRevenueValues(websiteId, {
+ startDate: new Date(startDate),
+ endDate: new Date(endDate),
+ });
+
+ return ok(res, data);
+ }
+
if (req.method === 'POST') {
const {
websiteId,
- dateRange: { startDate, endDate, unit, timezone },
- eventName,
- revenueProperty,
- userProperty,
+ currency,
+ timezone,
+ dateRange: { startDate, endDate, unit },
} = req.body;
if (!(await canViewWebsite(req.auth, websiteId))) {
@@ -59,9 +70,7 @@ export default async (
endDate: new Date(endDate),
unit,
timezone,
- eventName,
- revenueProperty,
- userProperty,
+ currency,
});
return ok(res, data);
diff --git a/src/pages/api/send.ts b/src/pages/api/send.ts
index 23640de9..fb4e90c7 100644
--- a/src/pages/api/send.ts
+++ b/src/pages/api/send.ts
@@ -96,7 +96,7 @@ export default async (req: NextApiRequestCollect, res: NextApiResponse) => {
}
const { type, payload } = req.body;
- const { url, referrer, name: eventName, data, title } = payload;
+ const { url, referrer, name: eventName, data, title, tag } = payload;
const pageTitle = safeDecodeURI(title);
await useSession(req, res);
@@ -143,6 +143,7 @@ export default async (req: NextApiRequestCollect, res: NextApiResponse) => {
eventData: data,
...session,
sessionId: session.id,
+ tag,
});
} else if (type === COLLECTION_TYPE.identify) {
if (!data) {
diff --git a/src/pages/api/websites/[websiteId]/event-data/fields.ts b/src/pages/api/websites/[websiteId]/event-data/fields.ts
new file mode 100644
index 00000000..c5075c5e
--- /dev/null
+++ b/src/pages/api/websites/[websiteId]/event-data/fields.ts
@@ -0,0 +1,51 @@
+import { canViewWebsite } from 'lib/auth';
+import { useAuth, useCors, useValidate } from 'lib/middleware';
+import { NextApiRequestQueryBody } from 'lib/types';
+import { NextApiResponse } from 'next';
+import { methodNotAllowed, ok, unauthorized } from 'next-basics';
+import { getEventDataFields } from 'queries';
+
+import * as yup from 'yup';
+
+export interface EventDataFieldsRequestQuery {
+ websiteId: string;
+ startAt: string;
+ endAt: string;
+}
+
+const schema = {
+ GET: yup.object().shape({
+ websiteId: yup.string().uuid().required(),
+ startAt: yup.number().integer().required(),
+ endAt: yup.number().integer().min(yup.ref('startAt')).required(),
+ }),
+};
+
+export default async (
+ req: NextApiRequestQueryBody,
+ res: NextApiResponse,
+) => {
+ await useCors(req, res);
+ await useAuth(req, res);
+ await useValidate(schema, req, res);
+
+ if (req.method === 'GET') {
+ const { websiteId, startAt, endAt } = req.query;
+
+ if (!(await canViewWebsite(req.auth, websiteId))) {
+ return unauthorized(res);
+ }
+
+ const startDate = new Date(+startAt);
+ const endDate = new Date(+endAt);
+
+ const data = await getEventDataFields(websiteId, {
+ startDate,
+ endDate,
+ });
+
+ return ok(res, data);
+ }
+
+ return methodNotAllowed(res);
+};
diff --git a/src/pages/api/websites/[websiteId]/events/stats.ts b/src/pages/api/websites/[websiteId]/event-data/stats.ts
similarity index 100%
rename from src/pages/api/websites/[websiteId]/events/stats.ts
rename to src/pages/api/websites/[websiteId]/event-data/stats.ts
diff --git a/src/pages/api/websites/[websiteId]/events/series.ts b/src/pages/api/websites/[websiteId]/events/series.ts
index 08cade12..6d67a264 100644
--- a/src/pages/api/websites/[websiteId]/events/series.ts
+++ b/src/pages/api/websites/[websiteId]/events/series.ts
@@ -24,6 +24,7 @@ export interface WebsiteEventsRequestQuery {
country?: string;
region: string;
city?: string;
+ tag?: string;
}
const schema = {
@@ -43,6 +44,7 @@ const schema = {
country: yup.string(),
region: yup.string(),
city: yup.string(),
+ tag: yup.string(),
}),
};
diff --git a/src/pages/api/websites/[websiteId]/metrics.ts b/src/pages/api/websites/[websiteId]/metrics.ts
index 3dac217b..1996a61a 100644
--- a/src/pages/api/websites/[websiteId]/metrics.ts
+++ b/src/pages/api/websites/[websiteId]/metrics.ts
@@ -29,6 +29,7 @@ export interface WebsiteMetricsRequestQuery {
limit?: number;
offset?: number;
search?: string;
+ tag?: string;
}
const schema = {
@@ -53,6 +54,7 @@ const schema = {
limit: yup.number(),
offset: yup.number(),
search: yup.string(),
+ tag: yup.string(),
}),
};
diff --git a/src/pages/api/websites/[websiteId]/pageviews.ts b/src/pages/api/websites/[websiteId]/pageviews.ts
index badb8a47..c3b6b797 100644
--- a/src/pages/api/websites/[websiteId]/pageviews.ts
+++ b/src/pages/api/websites/[websiteId]/pageviews.ts
@@ -25,6 +25,7 @@ export interface WebsitePageviewRequestQuery {
country?: string;
region: string;
city?: string;
+ tag?: string;
compare?: string;
}
@@ -45,6 +46,7 @@ const schema = {
country: yup.string(),
region: yup.string(),
city: yup.string(),
+ tag: yup.string(),
compare: yup.string(),
}),
};
diff --git a/src/pages/api/websites/[websiteId]/sessions/stats.ts b/src/pages/api/websites/[websiteId]/sessions/stats.ts
index a522bd6b..fe92ce6f 100644
--- a/src/pages/api/websites/[websiteId]/sessions/stats.ts
+++ b/src/pages/api/websites/[websiteId]/sessions/stats.ts
@@ -23,6 +23,7 @@ export interface WebsiteSessionStatsRequestQuery {
country?: string;
region?: string;
city?: string;
+ tag?: string;
}
const schema = {
@@ -42,6 +43,7 @@ const schema = {
country: yup.string(),
region: yup.string(),
city: yup.string(),
+ tag: yup.string(),
}),
};
diff --git a/src/pages/api/websites/[websiteId]/stats.ts b/src/pages/api/websites/[websiteId]/stats.ts
index 9ca84c74..dfc9198d 100644
--- a/src/pages/api/websites/[websiteId]/stats.ts
+++ b/src/pages/api/websites/[websiteId]/stats.ts
@@ -24,6 +24,7 @@ export interface WebsiteStatsRequestQuery {
country?: string;
region?: string;
city?: string;
+ tag?: string;
compare?: string;
}
@@ -44,6 +45,7 @@ const schema = {
country: yup.string(),
region: yup.string(),
city: yup.string(),
+ tag: yup.string(),
compare: yup.string(),
}),
};
diff --git a/src/queries/analytics/events/getEventDataFields.ts b/src/queries/analytics/events/getEventDataFields.ts
new file mode 100644
index 00000000..05fee072
--- /dev/null
+++ b/src/queries/analytics/events/getEventDataFields.ts
@@ -0,0 +1,69 @@
+import prisma from 'lib/prisma';
+import clickhouse from 'lib/clickhouse';
+import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
+import { QueryFilters, WebsiteEventData } from 'lib/types';
+
+export async function getEventDataFields(
+ ...args: [websiteId: string, filters: QueryFilters]
+): Promise {
+ return runQuery({
+ [PRISMA]: () => relationalQuery(...args),
+ [CLICKHOUSE]: () => clickhouseQuery(...args),
+ });
+}
+
+async function relationalQuery(websiteId: string, filters: QueryFilters) {
+ const { rawQuery, parseFilters, getDateSQL } = prisma;
+ const { filterQuery, params } = await parseFilters(websiteId, filters);
+
+ return rawQuery(
+ `
+ select
+ data_key as "propertyName",
+ data_type as "dataType",
+ case
+ when data_type = 2 then replace(string_value, '.0000', '')
+ when data_type = 4 then ${getDateSQL('date_value', 'hour')}
+ else string_value
+ end as "value",
+ count(*) as "total"
+ from event_data
+ join website_event on website_event.event_id = event_data.website_event_id
+ where event_data.website_id = {{websiteId::uuid}}
+ and event_data.created_at between {{startDate}} and {{endDate}}
+ ${filterQuery}
+ group by data_key, data_type, value
+ order by 2 desc
+ limit 100
+ `,
+ params,
+ );
+}
+
+async function clickhouseQuery(
+ websiteId: string,
+ filters: QueryFilters,
+): Promise<{ propertyName: string; dataType: number; propertyValue: string; total: number }[]> {
+ const { rawQuery, parseFilters } = clickhouse;
+ const { filterQuery, params } = await parseFilters(websiteId, filters);
+
+ return rawQuery(
+ `
+ select
+ data_key as propertyName,
+ data_type as dataType,
+ multiIf(data_type = 2, replaceAll(string_value, '.0000', ''),
+ data_type = 4, toString(date_trunc('hour', date_value)),
+ string_value) as "value",
+ count(*) as "total"
+ from event_data
+ where website_id = {websiteId:UUID}
+ and created_at between {startDate:DateTime64} and {endDate:DateTime64}
+ ${filterQuery}
+ group by data_key, data_type, value
+ order by 2 desc
+ limit 100
+ `,
+ params,
+ );
+}
diff --git a/src/queries/analytics/events/getEventDataValues.ts b/src/queries/analytics/events/getEventDataValues.ts
index 07e42307..63101824 100644
--- a/src/queries/analytics/events/getEventDataValues.ts
+++ b/src/queries/analytics/events/getEventDataValues.ts
@@ -49,7 +49,7 @@ async function relationalQuery(
async function clickhouseQuery(
websiteId: string,
filters: QueryFilters & { eventName?: string; propertyName?: string },
-): Promise<{ propertyName: string; dataType: number; propertyValue: string; total: number }[]> {
+): Promise<{ value: string; total: number }[]> {
const { rawQuery, parseFilters } = clickhouse;
const { filterQuery, params } = await parseFilters(websiteId, filters);
@@ -66,7 +66,7 @@ async function clickhouseQuery(
and data_key = {propertyName:String}
and event_name = {eventName:String}
${filterQuery}
- group by event_name, value
+ group by value
order by 2 desc
limit 100
`,
diff --git a/src/queries/analytics/events/saveEvent.ts b/src/queries/analytics/events/saveEvent.ts
index 6c0f917b..2424186a 100644
--- a/src/queries/analytics/events/saveEvent.ts
+++ b/src/queries/analytics/events/saveEvent.ts
@@ -28,6 +28,7 @@ export async function saveEvent(args: {
subdivision1?: string;
subdivision2?: string;
city?: string;
+ tag?: string;
}) {
return runQuery({
[PRISMA]: () => relationalQuery(args),
@@ -47,6 +48,7 @@ async function relationalQuery(data: {
pageTitle?: string;
eventName?: string;
eventData?: any;
+ tag?: string;
}) {
const {
websiteId,
@@ -60,6 +62,7 @@ async function relationalQuery(data: {
eventName,
eventData,
pageTitle,
+ tag,
} = data;
const websiteEventId = uuid();
@@ -77,6 +80,7 @@ async function relationalQuery(data: {
pageTitle: pageTitle?.substring(0, PAGE_TITLE_LENGTH),
eventType: eventName ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView,
eventName: eventName ? eventName?.substring(0, EVENT_NAME_LENGTH) : null,
+ tag,
},
});
@@ -116,6 +120,7 @@ async function clickhouseQuery(data: {
subdivision1?: string;
subdivision2?: string;
city?: string;
+ tag?: string;
}) {
const {
websiteId,
@@ -133,6 +138,7 @@ async function clickhouseQuery(data: {
subdivision1,
subdivision2,
city,
+ tag,
...args
} = data;
const { insert, getUTCString } = clickhouse;
@@ -145,7 +151,7 @@ async function clickhouseQuery(data: {
website_id: websiteId,
session_id: sessionId,
visit_id: visitId,
- event_id: uuid(),
+ event_id: eventId,
country: country,
subdivision1:
country && subdivision1
@@ -163,6 +169,7 @@ async function clickhouseQuery(data: {
page_title: pageTitle?.substring(0, PAGE_TITLE_LENGTH),
event_type: eventName ? EVENT_TYPE.customEvent : EVENT_TYPE.pageView,
event_name: eventName ? eventName?.substring(0, EVENT_NAME_LENGTH) : null,
+ tag: tag,
created_at: createdAt,
};
diff --git a/src/queries/analytics/reports/getRevenue.ts b/src/queries/analytics/reports/getRevenue.ts
index 502505f4..a2803e85 100644
--- a/src/queries/analytics/reports/getRevenue.ts
+++ b/src/queries/analytics/reports/getRevenue.ts
@@ -1,5 +1,5 @@
import clickhouse from 'lib/clickhouse';
-import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db';
+import { CLICKHOUSE, getDatabaseType, POSTGRESQL, PRISMA, runQuery } from 'lib/db';
import prisma from 'lib/prisma';
export async function getRevenue(
@@ -10,9 +10,7 @@ export async function getRevenue(
endDate: Date;
unit: string;
timezone: string;
- eventName: string;
- revenueProperty: string;
- userProperty: string;
+ currency: string;
},
]
) {
@@ -29,61 +27,115 @@ async function relationalQuery(
endDate: Date;
unit: string;
timezone: string;
- eventName: string;
- revenueProperty: string;
- userProperty: string;
+ currency: string;
},
): Promise<{
- chart: { time: string; sum: number; avg: number; count: number; uniqueCount: number }[];
- total: { sum: number; avg: number; count: number; uniqueCount: number };
+ chart: { x: string; t: string; y: number }[];
+ country: { name: string; value: number }[];
+ total: { sum: number; count: number; unique_count: number };
+ table: {
+ currency: string;
+ sum: number;
+ count: number;
+ unique_count: number;
+ }[];
}> {
- const {
- startDate,
- endDate,
- eventName,
- revenueProperty,
- userProperty,
- timezone = 'UTC',
- unit = 'day',
- } = criteria;
+ const { startDate, endDate, timezone = 'UTC', unit = 'day', currency } = criteria;
const { getDateSQL, rawQuery } = prisma;
+ const db = getDatabaseType();
+ const like = db === POSTGRESQL ? 'ilike' : 'like';
const chartRes = await rawQuery(
`
select
- ${getDateSQL('website_event.created_at', unit, timezone)} time,
- sum(case when data_key = {{revenueProperty}} then number_value else 0 end) sum,
- avg(case when data_key = {{revenueProperty}} then number_value else 0 end) avg,
- count(case when data_key = {{revenueProperty}} then 1 else 0 end) count,
- count(distinct {{userProperty}}) uniqueCount
- from event_data
- where website_event.website_id = {{websiteId::uuid}}
- and website_event.created_at between {{startDate}} and {{endDate}}
- and event_name = {{eventType}}
- and data_key in ({{revenueProperty}} , {{userProperty}})
- group by 1
+ we.event_name x,
+ ${getDateSQL('ed.created_at', unit, timezone)} t,
+ sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) y
+ from event_data ed
+ join website_event we
+ on we.event_id = ed.website_event_id
+ join (select website_event_id
+ from event_data
+ where data_key ${like} '%currency%'
+ and string_value = {{currency}}) currency
+ on currency.website_event_id = ed.website_event_id
+ where ed.website_id = {{websiteId::uuid}}
+ and ed.created_at between {{startDate}} and {{endDate}}
+ and ed.data_key ${like} '%revenue%'
+ group by x, t
+ order by t
`,
- { websiteId, startDate, endDate, eventName, revenueProperty, userProperty },
+ { websiteId, startDate, endDate, unit, timezone, currency },
+ );
+
+ const countryRes = await rawQuery(
+ `
+ select
+ s.country as name,
+ sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) value
+ from event_data ed
+ join website_event we
+ on we.event_id = ed.website_event_id
+ join session s
+ on s.session_id = we.session_id
+ join (select website_event_id
+ from event_data
+ where data_key ${like} '%currency%'
+ and string_value = {{currency}}) currency
+ on currency.website_event_id = ed.website_event_id
+ where ed.website_id = {{websiteId::uuid}}
+ and ed.created_at between {{startDate}} and {{endDate}}
+ and ed.data_key ${like} '%revenue%'
+ group by s.country
+ `,
+ { websiteId, startDate, endDate, currency },
);
const totalRes = await rawQuery(
`
select
- sum(case when data_key = {{revenueProperty}} then number_value else 0 end) sum,
- avg(case when data_key = {{revenueProperty}} then number_value else 0 end) avg,
- count(case when data_key = {{revenueProperty}} then 1 else 0 end) count,
- count(distinct {{userProperty}}) uniqueCount
- from event_data
- where website_event.website_id = {{websiteId::uuid}}
- and website_event.created_at between {{startDate}} and {{endDate}}
- and event_name = {{eventType}}
- and data_key in ({{revenueProperty}} , {{userProperty}})
- group by 1
+ sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as sum,
+ count(distinct event_id) as count,
+ count(distinct session_id) as unique_count
+ from event_data ed
+ join website_event we
+ on we.event_id = ed.website_event_id
+ join (select website_event_id
+ from event_data
+ where data_key ${like} '%currency%'
+ and string_value = {{currency}}) currency
+ on currency.website_event_id = ed.website_event_id
+ where ed.website_id = {{websiteId::uuid}}
+ and ed.created_at between {{startDate}} and {{endDate}}
+ and ed.data_key ${like} '%revenue%'
+ `,
+ { websiteId, startDate, endDate, currency },
+ ).then(result => result?.[0]);
+
+ const tableRes = await rawQuery(
+ `
+ select
+ c.currency,
+ sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as sum,
+ count(distinct ed.website_event_id) as count,
+ count(distinct we.session_id) as unique_count
+ from event_data ed
+ join website_event we
+ on we.event_id = ed.website_event_id
+ join (select website_event_id, string_value as currency
+ from event_data
+ where data_key ${like} '%currency%') c
+ on c.website_event_id = ed.website_event_id
+ where ed.website_id = {{websiteId::uuid}}
+ and ed.created_at between {{startDate}} and {{endDate}}
+ and ed.data_key ${like} '%revenue%'
+ group by c.currency
+ order by sum desc;
`,
- { websiteId, startDate, endDate, eventName, revenueProperty, userProperty },
+ { websiteId, startDate, endDate, unit, timezone, currency },
);
- return { chart: chartRes, total: totalRes };
+ return { chart: chartRes, country: countryRes, total: totalRes, table: tableRes };
}
async function clickhouseQuery(
@@ -91,80 +143,132 @@ async function clickhouseQuery(
criteria: {
startDate: Date;
endDate: Date;
- eventName: string;
- revenueProperty: string;
- userProperty: string;
unit: string;
timezone: string;
+ currency: string;
},
): Promise<{
- chart: { time: string; sum: number; avg: number; count: number; uniqueCount: number }[];
- total: { sum: number; avg: number; count: number; uniqueCount: number };
-}> {
- const {
- startDate,
- endDate,
- eventName,
- revenueProperty,
- userProperty = '',
- timezone = 'UTC',
- unit = 'day',
- } = criteria;
- const { getDateStringSQL, getDateSQL, rawQuery } = clickhouse;
-
- const chartRes = await rawQuery<{
- time: string;
+ chart: { x: string; t: string; y: number }[];
+ country: { name: string; value: number }[];
+ total: { sum: number; count: number; unique_count: number };
+ table: {
+ currency: string;
sum: number;
- avg: number;
count: number;
- uniqueCount: number;
- }>(
+ unique_count: number;
+ }[];
+}> {
+ const { startDate, endDate, timezone = 'UTC', unit = 'day', currency } = criteria;
+ const { getDateSQL, rawQuery } = clickhouse;
+
+ const chartRes = await rawQuery<
+ {
+ x: string;
+ t: string;
+ y: number;
+ }[]
+ >(
`
select
- ${getDateStringSQL('g.time', unit)} as time,
- g.sum as sum,
- g.avg as avg,
- g.count as count,
- g.uniqueCount as uniqueCount
- from (
- select
- ${getDateSQL('created_at', unit, timezone)} as time,
- sumIf(number_value, data_key = {revenueProperty:String}) as sum,
- avgIf(number_value, data_key = {revenueProperty:String}) as avg,
- countIf(data_key = {revenueProperty:String}) as count,
- uniqExactIf(string_value, data_key = {userProperty:String}) as uniqueCount
- from event_data
- where website_id = {websiteId:UUID}
- and created_at between {startDate:DateTime64} and {endDate:DateTime64}
- and event_name = {eventName:String}
- and data_key in ({revenueProperty:String}, {userProperty:String})
- group by time
- ) as g
- order by time
+ event_name x,
+ ${getDateSQL('created_at', unit, timezone)} t,
+ sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) y
+ from event_data
+ join (select event_id
+ from event_data
+ where positionCaseInsensitive(data_key, 'currency') > 0
+ and string_value = {currency:String}) currency
+ on currency.event_id = event_data.event_id
+ where website_id = {websiteId:UUID}
+ and created_at between {startDate:DateTime64} and {endDate:DateTime64}
+ and positionCaseInsensitive(data_key, 'revenue') > 0
+ group by x, t
+ order by t
`,
- { websiteId, startDate, endDate, eventName, revenueProperty, userProperty },
- ).then(result => result?.[0]);
+ { websiteId, startDate, endDate, unit, timezone, currency },
+ );
+
+ const countryRes = await rawQuery<
+ {
+ name: string;
+ value: number;
+ }[]
+ >(
+ `
+ select
+ s.country as name,
+ sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) as value
+ from event_data ed
+ join (select event_id
+ from event_data
+ where positionCaseInsensitive(data_key, 'currency') > 0
+ and string_value = {currency:String}) c
+ on c.event_id = ed.event_id
+ join (select distinct website_id, session_id, country
+ from website_event_stats_hourly
+ where website_id = {websiteId:UUID}) s
+ on ed.website_id = s.website_id
+ and ed.session_id = s.session_id
+ where ed.website_id = {websiteId:UUID}
+ and ed.created_at between {startDate:DateTime64} and {endDate:DateTime64}
+ and positionCaseInsensitive(ed.data_key, 'revenue') > 0
+ group by s.country
+ `,
+ { websiteId, startDate, endDate, currency },
+ );
const totalRes = await rawQuery<{
sum: number;
avg: number;
count: number;
- uniqueCount: number;
+ unique_count: number;
}>(
`
- select
- sumIf(number_value, data_key = {revenueProperty:String}) as sum,
- avgIf(number_value, data_key = {revenueProperty:String}) as avg,
- countIf(data_key = {revenueProperty:String}) as count,
- uniqExactIf(string_value, data_key = {userProperty:String}) as uniqueCount
- from event_data
- where website_id = {websiteId:UUID}
- and created_at between {startDate:DateTime64} and {endDate:DateTime64}
- and event_name = {eventName:String}
- and data_key in ({revenueProperty:String}, {userProperty:String})
+ select
+ sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) as sum,
+ uniqExact(event_id) as count,
+ uniqExact(session_id) as unique_count
+ from event_data
+ join (select event_id
+ from event_data
+ where positionCaseInsensitive(data_key, 'currency') > 0
+ and string_value = {currency:String}) currency
+ on currency.event_id = event_data.event_id
+ where website_id = {websiteId:UUID}
+ and created_at between {startDate:DateTime64} and {endDate:DateTime64}
+ and positionCaseInsensitive(data_key, 'revenue') > 0
`,
- { websiteId, startDate, endDate, eventName, revenueProperty, userProperty },
+ { websiteId, startDate, endDate, currency },
+ ).then(result => result?.[0]);
+
+ const tableRes = await rawQuery<
+ {
+ currency: string;
+ sum: number;
+ avg: number;
+ count: number;
+ unique_count: number;
+ }[]
+ >(
+ `
+ select
+ c.currency,
+ sum(coalesce(toDecimal64(ed.number_value, 2), toDecimal64(ed.string_value, 2))) as sum,
+ uniqExact(ed.event_id) as count,
+ uniqExact(ed.session_id) as unique_count
+ from event_data ed
+ join (select event_id, string_value as currency
+ from event_data
+ where positionCaseInsensitive(data_key, 'currency') > 0) c
+ on c.event_id = ed.event_id
+ where website_id = {websiteId:UUID}
+ and created_at between {startDate:DateTime64} and {endDate:DateTime64}
+ and positionCaseInsensitive(data_key, 'revenue') > 0
+ group by c.currency
+ order by sum desc;
+ `,
+ { websiteId, startDate, endDate, unit, timezone, currency },
);
- return { chart: chartRes, total: totalRes };
+ return { chart: chartRes, country: countryRes, total: totalRes, table: tableRes };
}
diff --git a/src/queries/analytics/reports/getRevenueValues.ts b/src/queries/analytics/reports/getRevenueValues.ts
new file mode 100644
index 00000000..4dcc4a22
--- /dev/null
+++ b/src/queries/analytics/reports/getRevenueValues.ts
@@ -0,0 +1,75 @@
+import prisma from 'lib/prisma';
+import clickhouse from 'lib/clickhouse';
+import { runQuery, CLICKHOUSE, PRISMA, getDatabaseType, POSTGRESQL } from 'lib/db';
+
+export async function getRevenueValues(
+ ...args: [
+ websiteId: string,
+ criteria: {
+ startDate: Date;
+ endDate: Date;
+ },
+ ]
+) {
+ return runQuery({
+ [PRISMA]: () => relationalQuery(...args),
+ [CLICKHOUSE]: () => clickhouseQuery(...args),
+ });
+}
+
+async function relationalQuery(
+ websiteId: string,
+ criteria: {
+ startDate: Date;
+ endDate: Date;
+ },
+) {
+ const { rawQuery } = prisma;
+ const { startDate, endDate } = criteria;
+
+ const db = getDatabaseType();
+ const like = db === POSTGRESQL ? 'ilike' : 'like';
+
+ return rawQuery(
+ `
+ select distinct string_value as currency
+ from event_data
+ where website_id = {{websiteId::uuid}}
+ and created_at between {{startDate}} and {{endDate}}
+ and data_key ${like} '%currency%'
+ order by currency
+ `,
+ {
+ websiteId,
+ startDate,
+ endDate,
+ },
+ );
+}
+
+async function clickhouseQuery(
+ websiteId: string,
+ criteria: {
+ startDate: Date;
+ endDate: Date;
+ },
+) {
+ const { rawQuery } = clickhouse;
+ const { startDate, endDate } = criteria;
+
+ return rawQuery(
+ `
+ select distinct string_value as currency
+ from event_data
+ where website_id = {websiteId:UUID}
+ and created_at between {startDate:DateTime64} and {endDate:DateTime64}
+ and positionCaseInsensitive(data_key, 'currency') > 0
+ order by currency
+ `,
+ {
+ websiteId,
+ startDate,
+ endDate,
+ },
+ );
+}
diff --git a/src/queries/analytics/sessions/getWebsiteSession.ts b/src/queries/analytics/sessions/getWebsiteSession.ts
index f9b9f39a..2c16741e 100644
--- a/src/queries/analytics/sessions/getWebsiteSession.ts
+++ b/src/queries/analytics/sessions/getWebsiteSession.ts
@@ -47,7 +47,7 @@ async function relationalQuery(websiteId: string, sessionId: string) {
min(website_event.created_at) as min_time,
max(website_event.created_at) as max_time,
sum(case when website_event.event_type = 1 then 1 else 0 end) as views,
- sum(case when website_event.event_type = 1 then 1 else 0 end) as events
+ sum(case when website_event.event_type = 2 then 1 else 0 end) as events
from session
join website_event on website_event.session_id = session.session_id
where session.website_id = {{websiteId::uuid}}
diff --git a/src/queries/analytics/sessions/getWebsiteSessionsWeekly.ts b/src/queries/analytics/sessions/getWebsiteSessionsWeekly.ts
index 153c9bb3..48d4f7a9 100644
--- a/src/queries/analytics/sessions/getWebsiteSessionsWeekly.ts
+++ b/src/queries/analytics/sessions/getWebsiteSessionsWeekly.ts
@@ -34,8 +34,8 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) {
async function clickhouseQuery(websiteId: string, filters: QueryFilters) {
const { timezone = 'utc' } = filters;
- const { rawQuery } = clickhouse;
- const { startDate, endDate } = filters;
+ const { rawQuery, parseFilters } = clickhouse;
+ const { params } = await parseFilters(websiteId, filters);
return rawQuery(
`
@@ -48,7 +48,7 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters) {
group by time
order by time
`,
- { websiteId, startDate, endDate },
+ params,
).then(formatResults);
}
diff --git a/src/queries/index.ts b/src/queries/index.ts
index a2697ced..8c7e564a 100644
--- a/src/queries/index.ts
+++ b/src/queries/index.ts
@@ -4,6 +4,7 @@ export * from 'queries/prisma/teamUser';
export * from 'queries/prisma/user';
export * from 'queries/prisma/website';
export * from './analytics/events/getEventDataEvents';
+export * from './analytics/events/getEventDataFields';
export * from './analytics/events/getEventDataProperties';
export * from './analytics/events/getEventDataValues';
export * from './analytics/events/getEventDataStats';
diff --git a/src/queries/prisma/user.ts b/src/queries/prisma/user.ts
index 9b471787..0c8e3520 100644
--- a/src/queries/prisma/user.ts
+++ b/src/queries/prisma/user.ts
@@ -171,6 +171,9 @@ export async function deleteUser(
client.eventData.deleteMany({
where: { websiteId: { in: websiteIds } },
}),
+ client.sessionData.deleteMany({
+ where: { websiteId: { in: websiteIds } },
+ }),
client.websiteEvent.deleteMany({
where: { websiteId: { in: websiteIds } },
}),
diff --git a/src/queries/prisma/website.ts b/src/queries/prisma/website.ts
index 0814a137..c24cdd0d 100644
--- a/src/queries/prisma/website.ts
+++ b/src/queries/prisma/website.ts
@@ -164,6 +164,9 @@ export async function resetWebsite(
client.eventData.deleteMany({
where: { websiteId },
}),
+ client.sessionData.deleteMany({
+ where: { websiteId },
+ }),
client.websiteEvent.deleteMany({
where: { websiteId },
}),
@@ -195,6 +198,9 @@ export async function deleteWebsite(
client.eventData.deleteMany({
where: { websiteId },
}),
+ client.sessionData.deleteMany({
+ where: { websiteId },
+ }),
client.websiteEvent.deleteMany({
where: { websiteId },
}),
diff --git a/src/styles/locale.css b/src/styles/locale.css
deleted file mode 100644
index dddf495b..00000000
--- a/src/styles/locale.css
+++ /dev/null
@@ -1,29 +0,0 @@
-.zh-CN {
- font-family: '方体', 'PingFang SC', '黑体', 'Heiti SC', 'Microsoft JhengHei UI',
- 'Microsoft JhengHei', Roboto, Noto, 'Noto Sans CJK SC', sans-serif !important;
-}
-
-.zh-TW {
- font-family: '方體', 'PingFang TC', '黑體', 'Heiti TC', 'Microsoft JhengHei UI',
- 'Microsoft JhengHei', Roboto, Noto, 'Noto Sans CJK TC', sans-serif !important;
-}
-
-.ja-JP {
- font-family: '游ゴシック体', YuGothic, 'ヒラギノ丸ゴ', 'Hiragino Sans', 'Yu Gothic UI',
- 'Meiryo UI', 'MS Gothic', Roboto, Noto, 'Noto Sans CJK JP', sans-serif !important;
-}
-
-.ko-KR {
- font-family: 'Nanum Gothic', 'Apple SD Gothic Neo', 'Malgun Gothic', Roboto, Noto,
- 'Noto Sans CJK KR', sans-serif !important;
-}
-
-.ar-SA {
- font-family: 'Geeza Pro', 'Arabic Typesetting', Roboto, Noto, 'Noto Naskh Arabic',
- 'Times New Roman', serif !important;
-}
-
-.he-IL {
- font-family: 'New Peninim MT', 'Arial Hebrew', Gisha, 'Times New Roman', Roboto, Noto,
- 'Noto Sans Hebrew', sans-serif !important;
-}
diff --git a/src/tracker/index.js b/src/tracker/index.js
index 707594cf..6b5b7066 100644
--- a/src/tracker/index.js
+++ b/src/tracker/index.js
@@ -3,12 +3,12 @@
screen: { width, height },
navigator: { language },
location,
- localStorage,
document,
history,
} = window;
const { hostname, href } = location;
const { currentScript, referrer } = document;
+ const localStorage = href.startsWith('data:') ? undefined : window.localStorage;
if (!currentScript) return;
@@ -53,8 +53,9 @@
const parseURL = url => {
try {
- const { pathname, search } = new URL(url);
- url = pathname + search;
+ // use location.origin as the base to handle cases where the url is a relative path
+ const { pathname, search, hash } = new URL(url, location.origin);
+ url = pathname + search + hash;
} catch (e) {
/* empty */
}
diff --git a/yarn.lock b/yarn.lock
index a53045fe..348bf68f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1113,9 +1113,9 @@
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.12.5":
- version "7.24.0"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e"
- integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==
+ version "7.26.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1"
+ integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==
dependencies:
regenerator-runtime "^0.14.0"
@@ -1199,17 +1199,17 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
-"@clickhouse/client-common@1.4.1":
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/@clickhouse/client-common/-/client-common-1.4.1.tgz#23c6ffbff5717729e533301c9f595cd79af221ef"
- integrity sha512-f5eoTrUSDplrMoi3ddeZ0MzGTn0iGMByEQ8j63eVMoBSOI2+F6jEIPcW2tWofT79Rvnn3RRlveYcShiaIiCJyw==
+"@clickhouse/client-common@1.8.0":
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/@clickhouse/client-common/-/client-common-1.8.0.tgz#6775c4f1f4b56f393cbacec0a1b544dafcf8d5ed"
+ integrity sha512-aQgH0UODGuFHfL8rgeLSrGCoh3NCoNUs0tFGl0o79iyfASfvWtT/K/X3RM0QJpXXOgXpB//T2nD5XvCFtdk32w==
"@clickhouse/client@^1.4.1":
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/@clickhouse/client/-/client-1.4.1.tgz#be4303d81f42835c5f168de61babd1a67d821f5a"
- integrity sha512-12iV+MeykxdQySRFHwaVU+hKUv3JP6kdwOI+z3zzyfPVYHynTlV8emJjjGZR0+VfRaj3PCMuQfryfsJ82nh9WQ==
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/@clickhouse/client/-/client-1.8.0.tgz#d891fae75efcf6e404ef1e810d4e2aceecabf8f4"
+ integrity sha512-IJ+/r3Wbg2t67sEtTA9dUgP2HjyGuze7ksNqeDfb7Ahnws1dzSVP2kg1Y9xOrb2e37K29JWWr26cX+rOiESm1A==
dependencies:
- "@clickhouse/client-common" "1.4.1"
+ "@clickhouse/client-common" "1.8.0"
"@colors/colors@1.5.0":
version "1.5.0"
@@ -1386,198 +1386,198 @@
resolved "https://registry.yarnpkg.com/@date-fns/utc/-/utc-1.2.0.tgz#fb705b025b6769840608782c8fa7f3919d1b3337"
integrity sha512-YLq+crMPJiBmIdkRmv9nZuZy1mVtMlDcUKlg4mvI0UsC/dZeIaGoGB5p/C4FrpeOhZ7zBTK03T58S0DFkRNMnw==
-"@dicebear/adventurer-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/adventurer-neutral/-/adventurer-neutral-9.2.1.tgz#0416ff71d0dd3ff391db9c9fda2acb166b074c5f"
- integrity sha512-iP6Tc6CgrJt63j08i/hlyNiGEbDNgP9Ws6WKT9n/0oTU9X/DKLncGStV3uhgYPIOVQE/tw9a/GjbGjrwBlN8CQ==
+"@dicebear/adventurer-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/adventurer-neutral/-/adventurer-neutral-9.2.2.tgz#2831c34c6e8818a319478b15b6b1741b95ef5bdb"
+ integrity sha512-XVAjhUWjav6luTZ7txz8zVJU/H0DiUy4uU1Z7IO5MDO6kWvum+If1+0OUgEWYZwM+RDI7rt2CgVP910DyZGd1w==
-"@dicebear/adventurer@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/adventurer/-/adventurer-9.2.1.tgz#3d522d2aaabe17d172ea2302bfdf62d601ebcd64"
- integrity sha512-utJr8oEOwPy9y+7rIOnB7mls+2XQrc3Kdlx/ay9KBY/HEUMnwMoN/GJhg4HcyGnV+DS7VhN6JSrnwwD9+SQyBw==
+"@dicebear/adventurer@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/adventurer/-/adventurer-9.2.2.tgz#cac7dddbd743078942df1391370191cbd235dde2"
+ integrity sha512-WjBXCP9EXbUul2zC3BS2/R3/4diw1uh/lU4jTEnujK1mhqwIwanFboIMzQsasNNL/xf+m3OHN7MUNJfHZ1fLZA==
-"@dicebear/avataaars-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/avataaars-neutral/-/avataaars-neutral-9.2.1.tgz#61d3894f4d08d9ee3722f3a64c36725729c6aaf3"
- integrity sha512-yceQMVBLimAHgZDL8VKCDGNs5JQ8BERaUMNIJXXRKEYZXlofoXZpYtcWPKQY9lmRJJznO1GX7ZK12ILnZjRPBQ==
+"@dicebear/avataaars-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/avataaars-neutral/-/avataaars-neutral-9.2.2.tgz#513369601d3e491b303c0760479da92b3f131883"
+ integrity sha512-pRj16P27dFDBI3LtdiHUDwIXIGndHAbZf5AxaMkn6/+0X93mVQ/btVJDXyW0G96WCsyC88wKAWr6/KJotPxU6Q==
-"@dicebear/avataaars@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/avataaars/-/avataaars-9.2.1.tgz#2460fb0d7d364a12e546b40b6e56c220db71c851"
- integrity sha512-WIZL7CWSsmzLswY/4ZrgtE/7EvnaNrYreLyT8hjiGyVb9J4cQaVZXSMuDIGFa5wT062AW/4/i82kh/7nh0oL+w==
+"@dicebear/avataaars@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/avataaars/-/avataaars-9.2.2.tgz#0c072c410ec5fdb8b5c5c7d440d038b02a42669e"
+ integrity sha512-WqJPQEt0OhBybTpI0TqU1uD1pSk9M2+VPIwvBye/dXo46b+0jHGpftmxjQwk6tX8z0+mRko8pwV5n+cWht1/+w==
-"@dicebear/big-ears-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/big-ears-neutral/-/big-ears-neutral-9.2.1.tgz#dfee12787f8a0efa7b3552fca5e9f24c9102fc44"
- integrity sha512-98qOCFEhbqCHeyO7ZXBAMMov8bquZt8vhtjj0YeHjGjI/OEWbA2gxq2ryv1BHSehVc/vTrd1KbHag7yYoeCDuw==
+"@dicebear/big-ears-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/big-ears-neutral/-/big-ears-neutral-9.2.2.tgz#98906d453f49896f948b0d6d93c07e95ad057a9a"
+ integrity sha512-IPHt8fi3dv9cyfBJBZ4s8T+PhFCrQvOCf91iRHBT3iOLNPdyZpI5GNLmGiV0XMAvIDP5NvA5+f6wdoBLhYhbDA==
-"@dicebear/big-ears@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/big-ears/-/big-ears-9.2.1.tgz#4a7f2f3d987c11d76602b6ee8b398f9dcd2ce486"
- integrity sha512-BUVTonwSYiGKcnk8wdwUHZ1b34GhfzRpG1kguK4kWAKlayBq7Q+iDJlmk4Bch0XdDQc2bqFf1GQCCj+xXWRHyg==
+"@dicebear/big-ears@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/big-ears/-/big-ears-9.2.2.tgz#66866ac6cfc4174ad875051892e40999e2f294a6"
+ integrity sha512-hz4UXdPq4qqZpu0YVvlqM4RDFhk5i0WgPcuwj/MOLlgTjuj63uHUhCQSk6ZiW1DQOs12qpwUBMGWVHxBRBas9g==
-"@dicebear/big-smile@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/big-smile/-/big-smile-9.2.1.tgz#d6cf95d34d65a393901925df370a1afbd0b0ae76"
- integrity sha512-bspur+wtnlv/Z4QDvRWg9rs3snf+iuBkamkgw4nZOUFKMlZdPQGqNoh1DkycRcLXNX1Q61KM172K6bS60ZlKxw==
+"@dicebear/big-smile@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/big-smile/-/big-smile-9.2.2.tgz#6ba6b385c16da3f94ae414b641848cbd498e13bb"
+ integrity sha512-D4td0GL8or1nTNnXvZqkEXlzyqzGPWs3znOnm1HIohtFTeIwXm72Ob2lNDsaQJSJvXmVlwaQQ0CCTvyCl8Stjw==
-"@dicebear/bottts-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/bottts-neutral/-/bottts-neutral-9.2.1.tgz#cc89b1ed834b7e8b7163dee2928dc1aa74077f75"
- integrity sha512-uwd+xcbRQUIHKQ1iEiLjf5RwCaVzOfBgIu2WRE+6MUaahYi6cJ0eJAs0h1q+zpgYyvqPDPDAi9j7AUwjmig0GA==
+"@dicebear/bottts-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/bottts-neutral/-/bottts-neutral-9.2.2.tgz#6e48ba93d69f7d5f82a743834b7972e5c1c8d967"
+ integrity sha512-lSgpqmSJtlnyxVuUgNdBwyzuA0O9xa5zRJtz7x2KyWbicXir5iYdX0MVMCkp1EDvlcxm9rGJsclktugOyakTlw==
-"@dicebear/bottts@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/bottts/-/bottts-9.2.1.tgz#922ccdba942d8c2c15655be0b6f25f4e9691cb80"
- integrity sha512-AQQ/WKd54G9sa+TkQptcu6c+Tjfc9hitgB70uA5GqJe+w6Bal+gwY6kPm5sJ1CY2mk/UBh1rXBuauQZ25bgTcQ==
+"@dicebear/bottts@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/bottts/-/bottts-9.2.2.tgz#8f2587469a5f6fe1a69c4b4ef5504455c3a4dd68"
+ integrity sha512-wugFkzw8JNWV1nftq/Wp/vmQsLAXDxrMtRK3AoMODuUpSVoP3EHRUfKS043xggOsQFvoj0HZ7kadmhn0AMLf5A==
"@dicebear/collection@^9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/collection/-/collection-9.2.1.tgz#b2de84ef654ac1550458a17049b02a0013213b92"
- integrity sha512-Su1eygO8llKuJ68N+xhBCzBN2Lqrsx9ZNdlvfZeH/s70RjL0raNQaI6/hRABDmlbLYwW4AjRh2lOgDdGfCp5DQ==
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/collection/-/collection-9.2.2.tgz#1f8affc2c19c670b7696e7c23a2fe4072dc64af4"
+ integrity sha512-vZAmXhPWCK3sf8Fj9/QflFC6XOLroJOT5K1HdnzHaPboEvffUQideGCrrEamnJtlH0iF0ZDXh8gqmwy2fu+yHA==
dependencies:
- "@dicebear/adventurer" "9.2.1"
- "@dicebear/adventurer-neutral" "9.2.1"
- "@dicebear/avataaars" "9.2.1"
- "@dicebear/avataaars-neutral" "9.2.1"
- "@dicebear/big-ears" "9.2.1"
- "@dicebear/big-ears-neutral" "9.2.1"
- "@dicebear/big-smile" "9.2.1"
- "@dicebear/bottts" "9.2.1"
- "@dicebear/bottts-neutral" "9.2.1"
- "@dicebear/croodles" "9.2.1"
- "@dicebear/croodles-neutral" "9.2.1"
- "@dicebear/dylan" "9.2.1"
- "@dicebear/fun-emoji" "9.2.1"
- "@dicebear/glass" "9.2.1"
- "@dicebear/icons" "9.2.1"
- "@dicebear/identicon" "9.2.1"
- "@dicebear/initials" "9.2.1"
- "@dicebear/lorelei" "9.2.1"
- "@dicebear/lorelei-neutral" "9.2.1"
- "@dicebear/micah" "9.2.1"
- "@dicebear/miniavs" "9.2.1"
- "@dicebear/notionists" "9.2.1"
- "@dicebear/notionists-neutral" "9.2.1"
- "@dicebear/open-peeps" "9.2.1"
- "@dicebear/personas" "9.2.1"
- "@dicebear/pixel-art" "9.2.1"
- "@dicebear/pixel-art-neutral" "9.2.1"
- "@dicebear/rings" "9.2.1"
- "@dicebear/shapes" "9.2.1"
- "@dicebear/thumbs" "9.2.1"
+ "@dicebear/adventurer" "9.2.2"
+ "@dicebear/adventurer-neutral" "9.2.2"
+ "@dicebear/avataaars" "9.2.2"
+ "@dicebear/avataaars-neutral" "9.2.2"
+ "@dicebear/big-ears" "9.2.2"
+ "@dicebear/big-ears-neutral" "9.2.2"
+ "@dicebear/big-smile" "9.2.2"
+ "@dicebear/bottts" "9.2.2"
+ "@dicebear/bottts-neutral" "9.2.2"
+ "@dicebear/croodles" "9.2.2"
+ "@dicebear/croodles-neutral" "9.2.2"
+ "@dicebear/dylan" "9.2.2"
+ "@dicebear/fun-emoji" "9.2.2"
+ "@dicebear/glass" "9.2.2"
+ "@dicebear/icons" "9.2.2"
+ "@dicebear/identicon" "9.2.2"
+ "@dicebear/initials" "9.2.2"
+ "@dicebear/lorelei" "9.2.2"
+ "@dicebear/lorelei-neutral" "9.2.2"
+ "@dicebear/micah" "9.2.2"
+ "@dicebear/miniavs" "9.2.2"
+ "@dicebear/notionists" "9.2.2"
+ "@dicebear/notionists-neutral" "9.2.2"
+ "@dicebear/open-peeps" "9.2.2"
+ "@dicebear/personas" "9.2.2"
+ "@dicebear/pixel-art" "9.2.2"
+ "@dicebear/pixel-art-neutral" "9.2.2"
+ "@dicebear/rings" "9.2.2"
+ "@dicebear/shapes" "9.2.2"
+ "@dicebear/thumbs" "9.2.2"
"@dicebear/core@^9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/core/-/core-9.2.1.tgz#b93800ac7e21ae955cceaa2370e7dc033a3cc557"
- integrity sha512-Y3E59+3xO2UWKdf3Zt/rwMdy9r7uccTgM89Kv8aXN1vmdrnA4YYmr4jslRRRqPLVpenuT4105nkboC4rMnDgHw==
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/core/-/core-9.2.2.tgz#dcaf941e4d9e79046d466b3197dfa3393288e5b2"
+ integrity sha512-ROhgHG249dPtcXgBHcqPEsDeAPRPRD/9d+tZCjLYyueO+cXDlIA8dUlxpwIVcOuZFvCyW6RJtqo8BhNAi16pIQ==
dependencies:
"@types/json-schema" "^7.0.11"
-"@dicebear/croodles-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/croodles-neutral/-/croodles-neutral-9.2.1.tgz#379646cf53ba4d61b6c94c13b3ec3386359e3541"
- integrity sha512-2iyr+B/y795P7cSIpFg4RjxUu6kljesKjtepvMzfeBR9xKyI84exBNHRoCTEVwOCFePmlPJX1qtw/YWM0sAPJw==
+"@dicebear/croodles-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/croodles-neutral/-/croodles-neutral-9.2.2.tgz#8eec838892dd5c9d8646fea7b46b57fe6ce3cf78"
+ integrity sha512-/4mNirxoQ+z1kHXnpDRbJ1JV1ZgXogeTeNp0MaFYxocCgHfJ7ckNM23EE1I7akoo9pqPxrKlaeNzGAjKHdS9vA==
-"@dicebear/croodles@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/croodles/-/croodles-9.2.1.tgz#74fa6aa8c0ee0dc303c0ad82fd78f5d6cd66610d"
- integrity sha512-V7+m21BizYTGgLgxmh5dxHHADeD3gkeuPYkhKqP8Uu8jZFBgh5wKFqqfVI/XSQkx/+lRla5c6l55mymgjt4k8Q==
+"@dicebear/croodles@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/croodles/-/croodles-9.2.2.tgz#7b2e2b1337bde23b582a8f5a04ef334f4f8c898a"
+ integrity sha512-OzvAXQWsOgMwL3Sl+lBxCubqSOWoBJpC78c4TKnNTS21rR63TtXUyVdLLzgKVN4YHRnvMgtPf8F/W9YAgIDK4w==
-"@dicebear/dylan@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/dylan/-/dylan-9.2.1.tgz#997aff74b4bf112e4895463eeea0adc2456d332f"
- integrity sha512-UeKz3Gxprh4bJ73Q2DjDpmjt854G3xfakc5KfeBmPV25EP+al7HCsM/HE+ZgKTSh+PPz5/mVtZQYU40pTzJEyg==
+"@dicebear/dylan@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/dylan/-/dylan-9.2.2.tgz#5ad87ae8c36f4edfffd87ab5fdf0fb4570ba682e"
+ integrity sha512-s7e3XliC1YXP+Wykj+j5kwdOWFRXFzYHYk/PB4oZ1F3sJandXiG0HS4chaNu4EoP0yZgKyFMUVTGZx+o6tMaYg==
-"@dicebear/fun-emoji@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/fun-emoji/-/fun-emoji-9.2.1.tgz#e88c8c2db7927d732ef2d0af3a24c4d4152a7f02"
- integrity sha512-F08p+Ggdxo4Ryji+3aCJXAKnjx4rM4UMtrJU4eA2t8lAkpwFNgfGK6mpMYPnxmKULYljGOgySmw7AyWcbX8s2Q==
+"@dicebear/fun-emoji@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/fun-emoji/-/fun-emoji-9.2.2.tgz#9f6786dc96068e1c8728765e675ddc8c6201bc77"
+ integrity sha512-M+rYTpB3lfwz18f+/i+ggNwNWUoEj58SJqXJ1wr7Jh/4E5uL+NmJg9JGwYNaVtGbCFrKAjSaILNUWGQSFgMfog==
-"@dicebear/glass@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/glass/-/glass-9.2.1.tgz#61bc231a5b0bd8d15cfa94c76ac608ab8fe98ac1"
- integrity sha512-UoErQwg7/qkEKWyEDTyt8FYhw/aZryP0Tr7cwBEuxMXZ585NUTvEel0K5j9aDkBrimJVEM+jKzOFIIMAGLlR0g==
+"@dicebear/glass@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/glass/-/glass-9.2.2.tgz#6c878fb8d2f380e3797c51d322b0dd013ea4b4b6"
+ integrity sha512-imCMxcg+XScHYtQq2MUv1lCzhQSCUglMlPSezKEpXhTxgbgUpmGlSGVkOfmX5EEc7SQowKkF1W/1gNk6CXvBaQ==
-"@dicebear/icons@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/icons/-/icons-9.2.1.tgz#0ef78e8ff742bd9985a3c36cd9cbd2705449e789"
- integrity sha512-0VuWohGMiv4n1nxwehYi6w+PIT9OBRlV721yNoewQWgQCrnMKBvM0cFRX9Dtg+MvwLMslQCIU3pEauEZ5FNmFA==
+"@dicebear/icons@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/icons/-/icons-9.2.2.tgz#c56168b574829a988105e360bc379868227d925e"
+ integrity sha512-Tqq2OVCdS7J02DNw58xwlgLGl40sWEckbqXT3qRvIF63FfVq+wQZBGuhuiyAURcSgvsc3h2oQeYFi9iXh7HTOA==
-"@dicebear/identicon@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/identicon/-/identicon-9.2.1.tgz#aebd7b692de9a6601746ab47711359f81471841c"
- integrity sha512-Dlqpn3tzqimR8KPIRkSJCKd5XwKgTLVXzT5KiY+2ysMZZQh4uJvBjVfY5SLrHDHC2a42W6EdwQxU6tFTRiKQuQ==
+"@dicebear/identicon@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/identicon/-/identicon-9.2.2.tgz#9210f5bf117b568ea59a30f3290ad55d8ab93087"
+ integrity sha512-POVKFulIrcuZf3rdAgxYaSm2XUg/TJg3tg9zq9150reEGPpzWR7ijyJ03dzAADPzS3DExfdYVT9+z3JKwwJnTQ==
-"@dicebear/initials@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/initials/-/initials-9.2.1.tgz#d4e435c18e48837f97086ba5210d4742594ba181"
- integrity sha512-d6Shnt1LiCf9yAEck3y/w4pXG4bWYVjBFCeI43l0BAR39Mk2Dq05UEFZH5Dtj2kyfNozMjh6vG1cQyBigtamug==
+"@dicebear/initials@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/initials/-/initials-9.2.2.tgz#f55fbcaa1a701b4c99251298f2e4c76e3ce8a260"
+ integrity sha512-/xNnsEmsstWjmF77htAOuwOMhFlP6eBVXgcgFlTl/CCH/Oc6H7t0vwX1he8KLQBBzjGpvJcvIAn4Wh9rE4D5/A==
-"@dicebear/lorelei-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/lorelei-neutral/-/lorelei-neutral-9.2.1.tgz#5d5d6400c0e2232081f58f8d82efff00ee307b81"
- integrity sha512-4YkkR697qXAYxN5N/zVsRe955QLhw0yLib2CzeBga1QXXMIkywq2nRFa3fr4toSRPl45kl1eF8J5HC17CU9inw==
+"@dicebear/lorelei-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/lorelei-neutral/-/lorelei-neutral-9.2.2.tgz#c7efaa5f4c7784863929a3b162a6c880920426ec"
+ integrity sha512-Eys9Os6nt2Xll7Mvu66CfRR2YggTopWcmFcRZ9pPdohS96kT0MsLI2iTcfZXQ51K8hvT3IbwoGc86W8n0cDxAQ==
-"@dicebear/lorelei@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/lorelei/-/lorelei-9.2.1.tgz#b23ddb02b098578ef1bcb121c7a638795f3de89e"
- integrity sha512-DNjZpUpe/CxKK8Byn1meBvRz/NJWtBizcoS2DzIIyqPYOwA5cLIa2g/qKkESvXzU9naEMkiHfMZb1RYYzN2FAA==
+"@dicebear/lorelei@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/lorelei/-/lorelei-9.2.2.tgz#2be5e72f8bd8bdae90e005e743872f563e825965"
+ integrity sha512-koXqVr/vcWUPo00VP5H6Czsit+uF1tmwd2NK7Q/e34/9Sd1f4QLLxHjjBNm/iNjCI1+UNTOvZ2Qqu0N5eo7Flw==
-"@dicebear/micah@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/micah/-/micah-9.2.1.tgz#2e65fdb15b6ee6338123329c92e5afb98f694718"
- integrity sha512-FK91igiVpPNhGCsfGpOgwYFKRP+FNR1V45Z4Tg/f82ux9TBdTmeoIfkgwrfhcXmCgagoYg2EAY+L72stUVapcA==
+"@dicebear/micah@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/micah/-/micah-9.2.2.tgz#8cded41bc857089b6df7530b81f20cf43e5dc7be"
+ integrity sha512-NCajcJV5yw8uMKiACp694w1T/UyYme2CUEzyTzWHgWnQ+drAuCcH8gpAoLWd67viNdQB/MTpNlaelUgTjmI4AQ==
-"@dicebear/miniavs@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/miniavs/-/miniavs-9.2.1.tgz#de1e571663775b4b2a30944d8033d6a8b972aca3"
- integrity sha512-r0TcaSrKJDPMqMYIiXNArq9i//cZzA1yuiXJw46iTloBDTh7yL1tpnL84CDxMpQ+OZLeMiRA6jVBx0coer4vmg==
+"@dicebear/miniavs@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/miniavs/-/miniavs-9.2.2.tgz#b588faf88c4dbfc8ab9de31da364b2bb31dcad5b"
+ integrity sha512-vvkWXttdw+KHF3j+9qcUFzK+P0nbNnImGjvN48wwkPIh2h08WWFq0MnoOls4IHwUJC4GXBjWtiyVoCxz6hhtOA==
-"@dicebear/notionists-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/notionists-neutral/-/notionists-neutral-9.2.1.tgz#2e77ae7330201628c4b3e4789b1aa83ffc684b82"
- integrity sha512-Vi/FwMXzc1m/U2TjBnY9NHedoLbPc3BBsNQL8jPU27wdkXoyJHuXBevcUtsF0Zf8OuRbNpZKPbfYy6OYBr9qvw==
+"@dicebear/notionists-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/notionists-neutral/-/notionists-neutral-9.2.2.tgz#d7b7fb70a742e528ec67bbf9fe608af51406a0fc"
+ integrity sha512-AhOzk+lz6kB4uxGun8AJhV+W1nttnMlxmxd+5KbQ/txCIziYIaeD3il44wsAGegEpGFvAZyMYtR/jjfHcem3TA==
-"@dicebear/notionists@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/notionists/-/notionists-9.2.1.tgz#70aa14e8846a49096648f891a625a92b04513c75"
- integrity sha512-oAyvPlp3xfFnDpW3nXhdAPGVm5WYj6VW6RgdzLAHoRO2EOYDNkQruIXd+d8JYo1DMTLUbgp3onr5AF9UU2OBzw==
+"@dicebear/notionists@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/notionists/-/notionists-9.2.2.tgz#d70b86392a0830351f026d6893380e8c7bf87467"
+ integrity sha512-Z9orRaHoj7Y9Ap4wEu8XOrFACsG1KbbBQUPV1R50uh6AHwsyNrm4cS84ICoGLvxgLNHHOae3YCjd8aMu2z19zg==
-"@dicebear/open-peeps@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/open-peeps/-/open-peeps-9.2.1.tgz#dd9be6721ff7226e3a0286aec699fd6b0e0ad2b2"
- integrity sha512-oPA/ljbPtuj2cdM0QtyJu2i24AaEMTIIk/FJbnrBK765WPnQcCZh84w+ZuInTMIfF9gYszNY34gaRD8Z6UiYxQ==
+"@dicebear/open-peeps@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/open-peeps/-/open-peeps-9.2.2.tgz#6f7aa648f02f8a0f24107b1ffcd462c8a065f3eb"
+ integrity sha512-6PeQDHYyjvKrGSl/gP+RE5dSYAQGKpcGnM65HorgyTIugZK7STo0W4hvEycedupZ3MCCEH8x/XyiChKM2sHXog==
-"@dicebear/personas@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/personas/-/personas-9.2.1.tgz#dfa8291ebba098e8cebdeb04a4fba9e4384c4496"
- integrity sha512-OgtyT9dnY8U60sUo0SLKCFVt0+dIr3a4vR0bDs/zwK4Qb/yTdB1VPdfxq0Fwk2q1vfn9YgbDrb0YYRgMRl60qQ==
+"@dicebear/personas@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/personas/-/personas-9.2.2.tgz#02b6787d91d1af4ab358eb5a49fb30f40b9a62a3"
+ integrity sha512-705+ObNLC0w1fcgE/Utav+8bqO+Esu53TXegpX5j7trGEoIMf2bThqJGHuhknZ3+T2az3Wr89cGyOGlI0KLzLA==
-"@dicebear/pixel-art-neutral@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/pixel-art-neutral/-/pixel-art-neutral-9.2.1.tgz#457b4e038c9516e75d41c6c1efd9ff9d4099162a"
- integrity sha512-GUtxJYX7/9XDgSZhkx24PB+yLcKkLHblDldvRr5xGlGxhgAovTBQFHLgCJxmUJgIaNW7pvSWCw7txguyxbBN9A==
+"@dicebear/pixel-art-neutral@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/pixel-art-neutral/-/pixel-art-neutral-9.2.2.tgz#2772edbff67fc993ecc9eb2c3099246f7a212f88"
+ integrity sha512-CdUY77H6Aj7dKLW3hdkv7tu0XQJArUjaWoXihQxlhl3oVYplWaoyu9omYy5pl8HTqs8YgVTGljjMXYoFuK0JUw==
-"@dicebear/pixel-art@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/pixel-art/-/pixel-art-9.2.1.tgz#e50bcc300a43c16ad3f69de1b6bf3dad92528274"
- integrity sha512-ftKPKCvnS1cJ2OvuQLmtEIwdb9PzF5C2ofWBdVI/RFvhH1BhYc3OsdQ28o90+ZJQO4fivKwfsh8MPUTaqToQ7Q==
+"@dicebear/pixel-art@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/pixel-art/-/pixel-art-9.2.2.tgz#6416f61e1c2825db516b6c467ce47596f9f865b8"
+ integrity sha512-BvbFdrpzQl04+Y9UsWP63YGug+ENGC7GMG88qbEFWxb/IqRavGa4H3D0T4Zl2PSLiw7f2Ctv98bsCQZ1PtCznQ==
-"@dicebear/rings@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/rings/-/rings-9.2.1.tgz#ed6e930c02b09ebbd774fc104cffc5c23ffa6b4c"
- integrity sha512-BlFYCaKB+wdpWWS28ZnQ/MvHeuNSRvkvWRoiw7pgS653LXx4kz/erVMmeVMSAr82y4BV+K8He2Rl2dMjuLyrXw==
+"@dicebear/rings@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/rings/-/rings-9.2.2.tgz#731b55b4a1442ae3edf89387841dc147181906a6"
+ integrity sha512-eD1J1k364Arny+UlvGrk12HP/XGG6WxPSm4BarFqdJGSV45XOZlwqoi7FlcMr9r9yvE/nGL8OizbwMYusEEdjw==
-"@dicebear/shapes@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/shapes/-/shapes-9.2.1.tgz#e076b9aabd67bf611e9bbf7149919000e3d74197"
- integrity sha512-cQzTcYimtuiAun55uPdIIhK53QTyjWqF/YN7LqEBGBqrJuGqHZBm1HXCcj7wPpoQ3zSy/2u8Rp0Etv7+5XFzyw==
+"@dicebear/shapes@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/shapes/-/shapes-9.2.2.tgz#440d1d97882bd476499d95e5180c04e30d721bc1"
+ integrity sha512-e741NNWBa7fg0BjomxXa0fFPME2XCIR0FA+VHdq9AD2taTGHEPsg5x1QJhCRdK6ww85yeu3V3ucpZXdSrHVw5Q==
-"@dicebear/thumbs@9.2.1":
- version "9.2.1"
- resolved "https://registry.yarnpkg.com/@dicebear/thumbs/-/thumbs-9.2.1.tgz#174be721256e5ff97e19586a54bde8fd25468e74"
- integrity sha512-ziX5HFmhiApO2k7QKj41+dGXbMdmQUUgFBYPyzTwnubhkDldJk7tpRoa5u2OsyTVDQCcPMv5mFSQpbANfmFwMg==
+"@dicebear/thumbs@9.2.2":
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/@dicebear/thumbs/-/thumbs-9.2.2.tgz#234814c889509682992bd3f93daaa960cb5326a2"
+ integrity sha512-FkPLDNu7n5kThLSk7lR/0cz/NkUqgGdZGfLZv6fLkGNGtv6W+e2vZaO7HCXVwIgJ+II+kImN41zVIZ6Jlll7pQ==
"@esbuild/android-arm64@0.17.19":
version "0.17.19"
@@ -1770,20 +1770,21 @@
dependencies:
tslib "^2.0.1"
-"@formatjs/ecma402-abstract@2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz#39197ab90b1c78b7342b129a56a7acdb8f512e17"
- integrity sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==
+"@formatjs/ecma402-abstract@2.2.3":
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.3.tgz#dc5a032e1971c709b32b9ab511fa35504a7d3bc9"
+ integrity sha512-aElGmleuReGnk2wtYOzYFmNWYoiWWmf1pPPCYg0oiIQSJj0mjc4eUfzUXaSOJ4S8WzI/cLqnCTWjqz904FT2OQ==
dependencies:
- "@formatjs/intl-localematcher" "0.5.4"
- tslib "^2.4.0"
+ "@formatjs/fast-memoize" "2.2.3"
+ "@formatjs/intl-localematcher" "0.5.7"
+ tslib "2"
-"@formatjs/fast-memoize@2.2.0":
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b"
- integrity sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==
+"@formatjs/fast-memoize@2.2.3":
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.3.tgz#74e64109279d5244f9fc281f3ae90c407cece823"
+ integrity sha512-3jeJ+HyOfu8osl3GNSL4vVHUuWFXR03Iz9jjgI7RwjG6ysu/Ymdr0JRCPHfF5yGbTE6JCrd63EpvX1/WybYRbA==
dependencies:
- tslib "^2.4.0"
+ tslib "2"
"@formatjs/icu-messageformat-parser@2.1.0":
version "2.1.0"
@@ -1794,14 +1795,14 @@
"@formatjs/icu-skeleton-parser" "1.3.6"
tslib "^2.1.0"
-"@formatjs/icu-messageformat-parser@2.7.8":
- version "2.7.8"
- resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz#f6d7643001e9bb5930d812f1f9a9856f30fa0343"
- integrity sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==
+"@formatjs/icu-messageformat-parser@2.9.3":
+ version "2.9.3"
+ resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.3.tgz#7785cb48ba980ebcbe67a0a3fe12837032b95518"
+ integrity sha512-9L99QsH14XjOCIp4TmbT8wxuffJxGK8uLNO1zNhLtcZaVXvv626N0s4A2qgRCKG3dfYWx9psvGlFmvyVBa6u/w==
dependencies:
- "@formatjs/ecma402-abstract" "2.0.0"
- "@formatjs/icu-skeleton-parser" "1.8.2"
- tslib "^2.4.0"
+ "@formatjs/ecma402-abstract" "2.2.3"
+ "@formatjs/icu-skeleton-parser" "1.8.7"
+ tslib "2"
"@formatjs/icu-skeleton-parser@1.3.6":
version "1.3.6"
@@ -1811,31 +1812,31 @@
"@formatjs/ecma402-abstract" "1.11.4"
tslib "^2.1.0"
-"@formatjs/icu-skeleton-parser@1.8.2":
- version "1.8.2"
- resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz#2252c949ae84ee66930e726130ea66731a123c9f"
- integrity sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==
+"@formatjs/icu-skeleton-parser@1.8.7":
+ version "1.8.7"
+ resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.7.tgz#c0c21d75428bf7213ac23a0efbf4dbfa868b800d"
+ integrity sha512-fI+6SmS2g7h3srfAKSWa5dwreU5zNEfon2uFo99OToiLF6yxGE+WikvFSbsvMAYkscucvVmTYNlWlaDPp0n5HA==
dependencies:
- "@formatjs/ecma402-abstract" "2.0.0"
- tslib "^2.4.0"
+ "@formatjs/ecma402-abstract" "2.2.3"
+ tslib "2"
-"@formatjs/intl-displaynames@6.6.8":
- version "6.6.8"
- resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.6.8.tgz#2f5afac8df83167f5a6ef8543600eaf1ef99c885"
- integrity sha512-Lgx6n5KxN16B3Pb05z3NLEBQkGoXnGjkTBNCZI+Cn17YjHJ3fhCeEJJUqRlIZmJdmaXQhjcQVDp6WIiNeRYT5g==
+"@formatjs/intl-displaynames@6.8.4":
+ version "6.8.4"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-6.8.4.tgz#5fbfa6fa08fd306bf4ed6f056eba12a71404cbbd"
+ integrity sha512-HDVNBspDAOW0yTWluWTPHX2fk/9iBO4oST4R96f/IUaPGsFtjsHrpakwc+XDRPa3U5RniSEU2z34ZY0W78+E6Q==
dependencies:
- "@formatjs/ecma402-abstract" "2.0.0"
- "@formatjs/intl-localematcher" "0.5.4"
- tslib "^2.4.0"
+ "@formatjs/ecma402-abstract" "2.2.3"
+ "@formatjs/intl-localematcher" "0.5.7"
+ tslib "2"
-"@formatjs/intl-listformat@7.5.7":
- version "7.5.7"
- resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.5.7.tgz#125e05105fabd1ae5f11881d6ab74484f2098ee4"
- integrity sha512-MG2TSChQJQT9f7Rlv+eXwUFiG24mKSzmF144PLb8m8OixyXqn4+YWU+5wZracZGCgVTVmx8viCf7IH3QXoiB2g==
+"@formatjs/intl-listformat@7.7.4":
+ version "7.7.4"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-7.7.4.tgz#a102e418f4b7846317e8835a31eecd670c428d0a"
+ integrity sha512-lipFspH2MZcoeXxR6WSR/Jy9unzJ/iT0w+gbL8vgv25Ap0S9cUtcDVAce4ECEKI1bDtAvEU3b6+9Dha27gAikA==
dependencies:
- "@formatjs/ecma402-abstract" "2.0.0"
- "@formatjs/intl-localematcher" "0.5.4"
- tslib "^2.4.0"
+ "@formatjs/ecma402-abstract" "2.2.3"
+ "@formatjs/intl-localematcher" "0.5.7"
+ tslib "2"
"@formatjs/intl-localematcher@0.2.25":
version "0.2.25"
@@ -1844,12 +1845,12 @@
dependencies:
tslib "^2.1.0"
-"@formatjs/intl-localematcher@0.5.4":
- version "0.5.4"
- resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz#caa71f2e40d93e37d58be35cfffe57865f2b366f"
- integrity sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==
+"@formatjs/intl-localematcher@0.5.7":
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.7.tgz#f889d076881b785d11ff993b966f527d199436d0"
+ integrity sha512-GGFtfHGQVFe/niOZp24Kal5b2i36eE2bNL0xi9Sg/yd0TR8aLjcteApZdHmismP5QQax1cMnZM9yWySUUjJteA==
dependencies:
- tslib "^2.4.0"
+ tslib "2"
"@formatjs/intl-numberformat@^5.5.2":
version "5.7.6"
@@ -1859,18 +1860,18 @@
"@formatjs/ecma402-abstract" "1.4.0"
tslib "^2.0.1"
-"@formatjs/intl@2.10.4":
- version "2.10.4"
- resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.10.4.tgz#e1819e0858fb05ca65923a020f346bc74e894e92"
- integrity sha512-56483O+HVcL0c7VucAS2tyH020mt9XTozZO67cwtGg0a7KWDukS/FzW3OnvaHmTHDuYsoPIzO+ZHVfU6fT/bJw==
+"@formatjs/intl@2.10.14":
+ version "2.10.14"
+ resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-2.10.14.tgz#3de1c6dfb39c286a4f48125740d45a5cb4dc3923"
+ integrity sha512-4CA1EO75i/mSMHdjwfpgRj3Rsdsm6WjALeu/nlzYhBmAPxGu/Ha5GIRHAet5SO05TnpmqxmEGOsskWqFm0IeoA==
dependencies:
- "@formatjs/ecma402-abstract" "2.0.0"
- "@formatjs/fast-memoize" "2.2.0"
- "@formatjs/icu-messageformat-parser" "2.7.8"
- "@formatjs/intl-displaynames" "6.6.8"
- "@formatjs/intl-listformat" "7.5.7"
- intl-messageformat "10.5.14"
- tslib "^2.4.0"
+ "@formatjs/ecma402-abstract" "2.2.3"
+ "@formatjs/fast-memoize" "2.2.3"
+ "@formatjs/icu-messageformat-parser" "2.9.3"
+ "@formatjs/intl-displaynames" "6.8.4"
+ "@formatjs/intl-listformat" "7.7.4"
+ intl-messageformat "10.7.6"
+ tslib "2"
"@formatjs/ts-transformer@3.9.4":
version "3.9.4"
@@ -2192,10 +2193,10 @@
resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
-"@netlify/plugin-nextjs@^5.1.0":
- version "5.6.0"
- resolved "https://registry.yarnpkg.com/@netlify/plugin-nextjs/-/plugin-nextjs-5.6.0.tgz#970f96b11bee4fe115fad8e3e4f3c6121f97a370"
- integrity sha512-PBrsd/GJZ9MN8BdyIoleTkY22lAUMfcRxrbb8wgxGzXtTW0RU0GW2mc99ISB6zOwWMZ11rSjeN0GS6znnukvww==
+"@netlify/plugin-nextjs@^5.8.1":
+ version "5.8.1"
+ resolved "https://registry.yarnpkg.com/@netlify/plugin-nextjs/-/plugin-nextjs-5.8.1.tgz#9da15bb4a13c5644e9b58b968c7da51939206ee4"
+ integrity sha512-WB1N0FslhWZ1yAVYTcB6CcFrFOUSQ0O2LfavYZrbAypeNxu2I+oO+cgmhfDgZ8Eoq1g4EMeoIGMkNoZ4ogZTsg==
"@next/env@14.2.10":
version "14.2.10"
@@ -2326,50 +2327,50 @@
dependencies:
"@prisma/debug" "5.17.0"
-"@react-spring/animated@~9.7.4":
- version "9.7.4"
- resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.4.tgz#c712b2d3dc9312ef41aa8886818b539151bda062"
- integrity sha512-7As+8Pty2QlemJ9O5ecsuPKjmO0NKvmVkRR1n6mEotFgWar8FKuQt2xgxz3RTgxcccghpx1YdS1FCdElQNexmQ==
+"@react-spring/animated@~9.7.5":
+ version "9.7.5"
+ resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.5.tgz#eb0373aaf99b879736b380c2829312dae3b05f28"
+ integrity sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==
dependencies:
- "@react-spring/shared" "~9.7.4"
- "@react-spring/types" "~9.7.4"
+ "@react-spring/shared" "~9.7.5"
+ "@react-spring/types" "~9.7.5"
-"@react-spring/core@~9.7.4":
- version "9.7.4"
- resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.7.4.tgz#0eaa0b5da3d18036d87a571f23079819d45a9f46"
- integrity sha512-GzjA44niEJBFUe9jN3zubRDDDP2E4tBlhNlSIkTChiNf9p4ZQlgXBg50qbXfSXHQPHak/ExYxwhipKVsQ/sUTw==
+"@react-spring/core@~9.7.5":
+ version "9.7.5"
+ resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.7.5.tgz#72159079f52c1c12813d78b52d4f17c0bf6411f7"
+ integrity sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==
dependencies:
- "@react-spring/animated" "~9.7.4"
- "@react-spring/shared" "~9.7.4"
- "@react-spring/types" "~9.7.4"
+ "@react-spring/animated" "~9.7.5"
+ "@react-spring/shared" "~9.7.5"
+ "@react-spring/types" "~9.7.5"
-"@react-spring/rafz@~9.7.4":
- version "9.7.4"
- resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.7.4.tgz#d53aa45a8cb116b81b27ba29e0cc15470ccfd449"
- integrity sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==
+"@react-spring/rafz@~9.7.5":
+ version "9.7.5"
+ resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.7.5.tgz#ee7959676e7b5d6a3813e8c17d5e50df98b95df9"
+ integrity sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==
-"@react-spring/shared@~9.7.4":
- version "9.7.4"
- resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.7.4.tgz#8ac57505072c2aee33d77c47c4269347061a3377"
- integrity sha512-bEPI7cQp94dOtCFSEYpxvLxj0+xQfB5r9Ru1h8OMycsIq7zFZon1G0sHrBLaLQIWeMCllc4tVDYRTLIRv70C8w==
+"@react-spring/shared@~9.7.5":
+ version "9.7.5"
+ resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.7.5.tgz#6d513622df6ad750bbbd4dedb4ca0a653ec92073"
+ integrity sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==
dependencies:
- "@react-spring/rafz" "~9.7.4"
- "@react-spring/types" "~9.7.4"
+ "@react-spring/rafz" "~9.7.5"
+ "@react-spring/types" "~9.7.5"
-"@react-spring/types@~9.7.4":
- version "9.7.4"
- resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.7.4.tgz#c849a7f062b5163d078e5e75f28c8f6acf91792e"
- integrity sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==
+"@react-spring/types@~9.7.5":
+ version "9.7.5"
+ resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.7.5.tgz#e5dd180f3ed985b44fd2cd2f32aa9203752ef3e8"
+ integrity sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==
"@react-spring/web@^9.7.3":
- version "9.7.4"
- resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.7.4.tgz#0086ab5dcf17e6a8f3d7e7f8041ccb4cc2fa10dc"
- integrity sha512-UMvCZp7I5HCVIleSa4BwbNxynqvj+mJjG2m20VO2yPoi2pnCYANy58flvz9v/YcXTAvsmL655FV3pm5fbr6akA==
+ version "9.7.5"
+ resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.7.5.tgz#7d7782560b3a6fb9066b52824690da738605de80"
+ integrity sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==
dependencies:
- "@react-spring/animated" "~9.7.4"
- "@react-spring/core" "~9.7.4"
- "@react-spring/shared" "~9.7.4"
- "@react-spring/types" "~9.7.4"
+ "@react-spring/animated" "~9.7.5"
+ "@react-spring/core" "~9.7.5"
+ "@react-spring/shared" "~9.7.5"
+ "@react-spring/types" "~9.7.5"
"@redis/bloom@1.2.0":
version "1.2.0"
@@ -2627,17 +2628,17 @@
"@swc/counter" "^0.1.3"
tslib "^2.4.0"
-"@tanstack/query-core@5.51.21":
- version "5.51.21"
- resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.51.21.tgz#a510469c6c30d3de2a8b8798e340169a4b0fd08f"
- integrity sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw==
+"@tanstack/query-core@5.59.20":
+ version "5.59.20"
+ resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.59.20.tgz#356718976536727b9af0ad1163a21fd6a44ee0a9"
+ integrity sha512-e8vw0lf7KwfGe1if4uPFhvZRWULqHjFcz3K8AebtieXvnMOz5FSzlZe3mTLlPuUBcydCnBRqYs2YJ5ys68wwLg==
"@tanstack/react-query@^5.28.6":
- version "5.51.23"
- resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.51.23.tgz#83c223f4cb6054b206de8856b73ca7e41a63ba1f"
- integrity sha512-CfJCfX45nnVIZjQBRYYtvVMIsGgWLKLYC4xcUiYEey671n1alvTZoCBaU9B85O8mF/tx9LPyrI04A6Bs2THv4A==
+ version "5.59.20"
+ resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.59.20.tgz#bacf1983f44c5690bb99b518f2ef71dc2fa875a4"
+ integrity sha512-Zly0egsK0tFdfSbh5/mapSa+Zfc3Et0Zkar7Wo5sQkFzWyB3p3uZWOHR2wrlAEEV2L953eLuDBtbgFvMYiLvUw==
dependencies:
- "@tanstack/query-core" "5.51.21"
+ "@tanstack/query-core" "5.59.20"
"@trysound/sax@0.2.0":
version "0.2.0"
@@ -2761,18 +2762,18 @@
dependencies:
"@types/node" "*"
-"@types/hoist-non-react-statics@^3.3.0":
- version "3.3.4"
- resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.4.tgz#cc477ce0283bb9d19ea0cbfa2941fe2c8493a1be"
- integrity sha512-ZchYkbieA+7tnxwX/SCBySx9WwvWR8TaP5tb2jRAzwvLb/rWchGw3v0w3pqUbUvj0GCwW2Xz/AVPSk6kUGctXQ==
+"@types/hoist-non-react-statics@3":
+ version "3.3.5"
+ resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
+ integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
-"@types/hoist-non-react-statics@^3.3.1":
- version "3.3.5"
- resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
- integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
+"@types/hoist-non-react-statics@^3.3.0":
+ version "3.3.4"
+ resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.4.tgz#cc477ce0283bb9d19ea0cbfa2941fe2c8493a1be"
+ integrity sha512-ZchYkbieA+7tnxwX/SCBySx9WwvWR8TaP5tb2jRAzwvLb/rWchGw3v0w3pqUbUvj0GCwW2Xz/AVPSk6kUGctXQ==
dependencies:
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
@@ -2874,9 +2875,9 @@
integrity sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==
"@types/prop-types@*":
- version "15.7.12"
- resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6"
- integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==
+ version "15.7.13"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451"
+ integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==
"@types/react-dom@^18.2.17":
version "18.3.0"
@@ -2902,7 +2903,15 @@
dependencies:
"@types/react" "*"
-"@types/react@*", "@types/react@16 || 17 || 18", "@types/react@^18.2.41":
+"@types/react@*", "@types/react@16 || 17 || 18":
+ version "18.3.12"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60"
+ integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^3.0.2"
+
+"@types/react@^18.2.41":
version "18.3.3"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f"
integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==
@@ -3933,9 +3942,9 @@ charenc@0.0.2:
integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==
chart.js@^4.4.2:
- version "4.4.3"
- resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.3.tgz#3b2e11e7010fefa99b07d0349236f5098e5226ad"
- integrity sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==
+ version "4.4.6"
+ resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.4.6.tgz#da39b84ca752298270d4c0519675c7659936abec"
+ integrity sha512-8Y406zevUPbbIBA/HRk33khEmQPk5+cxeflWE/2rx1NJsjVWMPw/9mSP9rxHP5eqi6LNoPBVMfZHxbwLSgldYA==
dependencies:
"@kurkle/color" "^0.3.0"
@@ -4206,7 +4215,7 @@ cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
-cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
+cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@@ -4215,6 +4224,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
+cross-spawn@^7.0.3:
+ version "7.0.5"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.5.tgz#910aac880ff5243da96b728bc6521a5f6c2f2f82"
+ integrity sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
@@ -4649,13 +4667,20 @@ debug@^3.1.0, debug@^3.2.7:
dependencies:
ms "^2.1.1"
-debug@^4.1.1, debug@^4.3.4:
+debug@^4.1.1:
version "4.3.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b"
integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==
dependencies:
ms "2.1.2"
+debug@^4.3.4:
+ version "4.3.7"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
+ integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
+ dependencies:
+ ms "^2.1.3"
+
decamelize-keys@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8"
@@ -6107,7 +6132,7 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2:
dependencies:
function-bind "^1.1.2"
-hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
+hoist-non-react-statics@3, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -6297,15 +6322,15 @@ intl-messageformat-parser@^5.3.7:
dependencies:
"@formatjs/intl-numberformat" "^5.5.2"
-intl-messageformat@10.5.14:
- version "10.5.14"
- resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.14.tgz#e5bb373f8a37b88fbe647d7b941f3ab2a37ed00a"
- integrity sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==
+intl-messageformat@10.7.6:
+ version "10.7.6"
+ resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.7.6.tgz#d486c780508a2fb8c383e95462951276cf0bcdf4"
+ integrity sha512-IsMU/hqyy3FJwNJ0hxDfY2heJ7MteSuFvcnCebxRp67di4Fhx1gKKE+qS0bBwUF8yXkX9SsPUhLeX/B6h5SKUA==
dependencies:
- "@formatjs/ecma402-abstract" "2.0.0"
- "@formatjs/fast-memoize" "2.2.0"
- "@formatjs/icu-messageformat-parser" "2.7.8"
- tslib "^2.4.0"
+ "@formatjs/ecma402-abstract" "2.2.3"
+ "@formatjs/fast-memoize" "2.2.3"
+ "@formatjs/icu-messageformat-parser" "2.9.3"
+ tslib "2"
ipaddr.js@^2.0.1:
version "2.2.0"
@@ -6617,9 +6642,9 @@ isarray@^2.0.5:
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
isbot@^5.1.16:
- version "5.1.16"
- resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.16.tgz#652fac0ab5ba181cefc53aa156edcb76f28ac07d"
- integrity sha512-zvRjcw/4UfKiCVx+/PqXPKthufO5m2PpJSbA0tVZY9ns7hlQRV1xqWpEFcqyfkK/MrChsXPmu1zpxECjcaEuKg==
+ version "5.1.17"
+ resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.17.tgz#ad7da5690a61bbb19056a069975c9a73182682a0"
+ integrity sha512-/wch8pRKZE+aoVhRX/hYPY1C7dMCeeMyhkQLNLNlYAbGQn9bkvMB8fOUXNnk5I0m4vDYbBJ9ciVtkr9zfBJ7qA==
isexe@^2.0.0:
version "2.0.0"
@@ -7825,9 +7850,9 @@ mmdb-lib@2.1.1:
integrity sha512-yx8H/1H5AfnufiLnzzPqPf4yr/dKU9IFT1rPVwSkrKWHsQEeVVd6+X+L0nUbXhlEFTu3y/7hu38CFmEVgzvyeg==
moment-timezone@^0.5.35:
- version "0.5.45"
- resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.45.tgz#cb685acd56bac10e69d93c536366eb65aa6bcf5c"
- integrity sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==
+ version "0.5.46"
+ resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.46.tgz#a21aa6392b3c6b3ed916cd5e95858a28d893704a"
+ integrity sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw==
dependencies:
moment "^2.29.4"
@@ -7841,7 +7866,7 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-ms@^2.1.1:
+ms@^2.1.1, ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -9048,9 +9073,9 @@ react-dom@^18.2.0:
scheduler "^0.23.2"
react-error-boundary@^4.0.4:
- version "4.0.13"
- resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.0.13.tgz#80386b7b27b1131c5fbb7368b8c0d983354c7947"
- integrity sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.1.2.tgz#bc750ad962edb8b135d6ae922c046051eb58f289"
+ integrity sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==
dependencies:
"@babel/runtime" "^7.12.5"
@@ -9060,20 +9085,20 @@ react-hook-form@^7.34.2:
integrity sha512-F/TroLjTICipmHeFlMrLtNLceO2xr1jU3CyiNla5zdwsGUGu2UOxxR4UyJgLlhMwLW/Wzp4cpJ7CPfgJIeKdSg==
react-intl@^6.5.5:
- version "6.6.8"
- resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.6.8.tgz#cb60c90502d0025caf9f86ec298cdc4348da17c2"
- integrity sha512-M0pkhzcgV31h++2901BiRXWl69hp2zPyLxRrSwRjd1ErXbNoubz/f4M6DrRTd4OiSUrT4ajRQzrmtS5plG4FtA==
+ version "6.8.7"
+ resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-6.8.7.tgz#e6f08f365810a366031358ff1c7dd8cf7e649bdd"
+ integrity sha512-Ocv8Tg6fXqBdVdkkYohQ79T9rJls3G1lmDSjhqHdK9873BdQFLSeITGgwuGWTRBd6Mg5FL33TBen4FtujCTP0g==
dependencies:
- "@formatjs/ecma402-abstract" "2.0.0"
- "@formatjs/icu-messageformat-parser" "2.7.8"
- "@formatjs/intl" "2.10.4"
- "@formatjs/intl-displaynames" "6.6.8"
- "@formatjs/intl-listformat" "7.5.7"
- "@types/hoist-non-react-statics" "^3.3.1"
+ "@formatjs/ecma402-abstract" "2.2.3"
+ "@formatjs/icu-messageformat-parser" "2.9.3"
+ "@formatjs/intl" "2.10.14"
+ "@formatjs/intl-displaynames" "6.8.4"
+ "@formatjs/intl-listformat" "7.7.4"
+ "@types/hoist-non-react-statics" "3"
"@types/react" "16 || 17 || 18"
- hoist-non-react-statics "^3.3.2"
- intl-messageformat "10.5.14"
- tslib "^2.4.0"
+ hoist-non-react-statics "3"
+ intl-messageformat "10.7.6"
+ tslib "2"
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
@@ -9482,9 +9507,9 @@ rollup-pluginutils@^2.8.2:
estree-walker "^0.6.1"
rollup@^3.28.0:
- version "3.29.4"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981"
- integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==
+ version "3.29.5"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.5.tgz#8a2e477a758b520fb78daf04bca4c522c1da8a54"
+ integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==
optionalDependencies:
fsevents "~2.3.2"
@@ -10353,6 +10378,11 @@ tsconfig-paths@^3.15.0:
minimist "^1.2.6"
strip-bom "^3.0.0"
+tslib@2, tslib@^2.4.0:
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
+ integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+
tslib@^1.8.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -10363,7 +10393,7 @@ tslib@^2.0.1, tslib@^2.0.3:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
-tslib@^2.1.0, tslib@^2.4.0:
+tslib@^2.1.0:
version "2.6.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==