diff --git a/.eslintrc.json b/.eslintrc.json index 7a824ff6..a77ed5bd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -19,22 +19,21 @@ "plugin:@typescript-eslint/recommended", "next" ], - "plugins": ["@typescript-eslint", "prettier"], "settings": { "import/resolver": { "alias": { "map": [ - ["assets", "./assets"], - ["components", "./components"], + ["assets", "./src/assets"], + ["components", "./src/components"], ["db", "./db"], - ["hooks", "./hooks"], - ["lang", "./lang"], - ["lib", "./lib"], + ["hooks", "./src/components/hooks"], + ["lang", "./src/lang"], + ["lib", "./src/lib"], ["public", "./public"], - ["queries", "./queries"], - ["store", "./store"], - ["styles", "./styles"] + ["queries", "./src/queries"], + ["store", "./src/store"], + ["styles", "./src/styles"] ], "extensions": [".ts", ".tsx", ".js", ".jsx", ".json"] } @@ -50,7 +49,9 @@ "@next/next/no-img-element": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-var-requires": "off" + "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-unused-vars": ["error", { "ignoreRestSiblings": true }] }, "globals": { "React": "writable" diff --git a/.github/ISSUE_TEMPLATE/2.feature_request.yml b/.github/ISSUE_TEMPLATE/2.feature_request.yml index 3034767b..529a6c73 100644 --- a/.github/ISSUE_TEMPLATE/2.feature_request.yml +++ b/.github/ISSUE_TEMPLATE/2.feature_request.yml @@ -1,10 +1,9 @@ -name: "✨ Feature Request" +name: '✨ Feature Request' description: Create a feature or enhancement request for Umami. -labels: ['enhancement'] body: - type: textarea attributes: label: Describe the feature or enhancement description: A clear and concise description of what the feature or enhancement is. validations: - required: true \ No newline at end of file + required: true diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 2dc5b675..00000000 --- a/.github/stale.yml +++ /dev/null @@ -1,19 +0,0 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 60 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 7 -# Issues with these labels will never be considered stale -exemptLabels: - - pinned - - security - - enhancement - - bug -# Label to use when marking an issue as stale -staleLabel: wontfix -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false diff --git a/.github/workflows/cd-manual.yml b/.github/workflows/cd-manual.yml index 1afc6e93..ac701fcc 100644 --- a/.github/workflows/cd-manual.yml +++ b/.github/workflows/cd-manual.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v3 - uses: mr-smithers-excellent/docker-build-push@v6 - name: Build & push Docker image for ${{ matrix.db-type }} + name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }} with: image: umami tags: ${{ matrix.db-type }}-${{ inputs.version }}, ${{ matrix.db-type }}-latest @@ -31,3 +31,13 @@ jobs: platform: linux/amd64,linux/arm64 username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - uses: mr-smithers-excellent/docker-build-push@v6 + name: Build & push Docker image to docker.io for ${{ matrix.db-type }} + with: + image: umamisoftware/umami + tags: ${{ matrix.db-type }}-${{ inputs.version }}, ${{ matrix.db-type }}-latest + buildArgs: DATABASE_TYPE=${{ matrix.db-type }} + registry: docker.io + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 6fda05a6..0660bcba 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -19,7 +19,7 @@ jobs: run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - uses: mr-smithers-excellent/docker-build-push@v6 - name: Build & push Docker image for ${{ matrix.db-type }} + name: Build & push Docker image to ghcr.io for ${{ matrix.db-type }} with: image: umami tags: ${{ matrix.db-type }}-${{ env.RELEASE_VERSION }}, ${{ matrix.db-type }}-latest @@ -29,3 +29,13 @@ jobs: platform: linux/amd64,linux/arm64 username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - uses: mr-smithers-excellent/docker-build-push@v6 + name: Build & push Docker image to docker.io for ${{ matrix.db-type }} + with: + image: umamisoftware/umami + tags: ${{ matrix.db-type }}-${{ env.RELEASE_VERSION }}, ${{ matrix.db-type }}-latest + buildArgs: DATABASE_TYPE=${{ matrix.db-type }} + registry: docker.io + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 307107b2..775f9ecf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,27 +16,24 @@ jobs: strategy: matrix: include: - - node-version: 14.x - db-type: postgresql - - node-version: 14.x - db-type: mysql - - node-version: 16.x - db-type: postgresql - - node-version: 16.x - db-type: mysql - - node-version: 18.x - db-type: postgresql - - node-version: 18.x - db-type: mysql + - node-version: 16.x + db-type: postgresql + - node-version: 16.x + db-type: mysql + - node-version: 18.x + db-type: postgresql + - node-version: 18.x + db-type: mysql + steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - env: - DATABASE_TYPE: ${{ matrix.db-type }} - - run: npm install --global yarn - - run: yarn install --frozen-lockfile - - run: yarn build + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + env: + DATABASE_TYPE: ${{ matrix.db-type }} + - run: npm install --global yarn + - run: yarn install --frozen-lockfile + - run: yarn build diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml new file mode 100644 index 00000000..24711fba --- /dev/null +++ b/.github/workflows/stale-issues.yml @@ -0,0 +1,24 @@ +name: Close stale issues +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v8 + with: + days-before-issue-stale: 60 + days-before-issue-close: 7 + stale-issue-label: 'stale' + stale-issue-message: 'This issue is stale because it has been open for 60 days with no activity.' + close-issue-message: 'This issue was closed because it has been inactive for 7 days since being marked as stale.' + days-before-pr-stale: -1 + days-before-pr-close: -1 + operations-per-run: 200 + ascending: true + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 7066fb28..99087ab5 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ node_modules *.iml *.log .vscode +.tool-versions # debug npm-debug.log* diff --git a/assets/add-user.svg b/assets/add-user.svg deleted file mode 100644 index 9d0544c6..00000000 --- a/assets/add-user.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/dashboard.svg b/assets/dashboard.svg deleted file mode 100644 index 11859d28..00000000 --- a/assets/dashboard.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/components/common/HoverTooltip.module.css b/components/common/HoverTooltip.module.css deleted file mode 100644 index ec1abc1c..00000000 --- a/components/common/HoverTooltip.module.css +++ /dev/null @@ -1,43 +0,0 @@ -.chart { - position: relative; -} - -.tooltip { - position: fixed; - pointer-events: none; - z-index: var(--z-index-popup); -} - -.content { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; -} - -.title { - font-size: var(--font-size-xs); - font-weight: 600; -} - -.metric { - display: flex; - justify-content: center; - align-items: center; - font-size: var(--font-size-sm); - font-weight: 600; -} - -.dot { - position: relative; - overflow: hidden; - border-radius: 100%; - margin-right: 8px; - background: var(--base50); -} - -.color { - width: 10px; - height: 10px; -} diff --git a/components/common/NoData.js b/components/common/NoData.js deleted file mode 100644 index e9c95754..00000000 --- a/components/common/NoData.js +++ /dev/null @@ -1,15 +0,0 @@ -import classNames from 'classnames'; -import styles from './NoData.module.css'; -import useMessages from 'hooks/useMessages'; - -export function NoData({ className }) { - const { formatMessage, messages } = useMessages(); - - return ( -
- {formatMessage(messages.noDataAvailable)} -
- ); -} - -export default NoData; diff --git a/components/common/SettingsTable.js b/components/common/SettingsTable.js deleted file mode 100644 index 8f039858..00000000 --- a/components/common/SettingsTable.js +++ /dev/null @@ -1,38 +0,0 @@ -import { Table, TableHeader, TableBody, TableRow, TableCell, TableColumn } from 'react-basics'; -import styles from './SettingsTable.module.css'; - -export function SettingsTable({ columns = [], data = [], children, cellRender }) { - return ( - - - {(column, index) => { - return ( - - {column.label} - - ); - }} - - - {(row, keys, rowIndex) => { - row.action = children(row, keys, rowIndex); - - return ( - - {(data, key, colIndex) => { - return ( - - - {cellRender ? cellRender(row, data, key, colIndex) : data[key]} - - ); - }} - - ); - }} - -
- ); -} - -export default SettingsTable; diff --git a/components/input/LanguageButton.js b/components/input/LanguageButton.js deleted file mode 100644 index 1297d6c2..00000000 --- a/components/input/LanguageButton.js +++ /dev/null @@ -1,47 +0,0 @@ -import { Icon, Button, PopupTrigger, Popup, Text } from 'react-basics'; -import classNames from 'classnames'; -import { languages } from 'lib/lang'; -import useLocale from 'hooks/useLocale'; -import Icons from 'components/icons'; -import styles from './LanguageButton.module.css'; - -export function LanguageButton() { - const { locale, saveLocale, dir } = useLocale(); - const items = Object.keys(languages).map(key => ({ ...languages[key], value: key })); - - function handleSelect(value) { - saveLocale(value); - } - - return ( - - - -
- {items.map(({ value, label }) => { - return ( -
- {label} - {value === locale && ( - - - - )} -
- ); - })} -
-
-
- ); -} - -export default LanguageButton; diff --git a/components/input/RefreshButton.js b/components/input/RefreshButton.js deleted file mode 100644 index b3e2b815..00000000 --- a/components/input/RefreshButton.js +++ /dev/null @@ -1,32 +0,0 @@ -import { LoadingButton, Icon, Tooltip } from 'react-basics'; -import { setWebsiteDateRange } from 'store/websites'; -import useDateRange from 'hooks/useDateRange'; -import Icons from 'components/icons'; -import useMessages from 'hooks/useMessages'; - -export function RefreshButton({ websiteId, isLoading }) { - const { formatMessage, labels } = useMessages(); - const [dateRange] = useDateRange(websiteId); - - function handleClick() { - if (!isLoading && dateRange) { - if (/^\d+/.test(dateRange.value)) { - setWebsiteDateRange(websiteId, dateRange.value); - } else { - setWebsiteDateRange(websiteId, dateRange); - } - } - } - - return ( - - - - - - - - ); -} - -export default RefreshButton; diff --git a/components/layout/Footer.js b/components/layout/Footer.js deleted file mode 100644 index 7cc5d3de..00000000 --- a/components/layout/Footer.js +++ /dev/null @@ -1,33 +0,0 @@ -import { Row, Column } from 'react-basics'; -import { FormattedMessage } from 'react-intl'; -import { CURRENT_VERSION, HOMEPAGE_URL, REPO_URL } from 'lib/constants'; -import { labels } from 'components/messages'; -import styles from './Footer.module.css'; - -export function Footer() { - return ( - - ); -} - -export default Footer; diff --git a/components/layout/Footer.module.css b/components/layout/Footer.module.css deleted file mode 100644 index a23f496d..00000000 --- a/components/layout/Footer.module.css +++ /dev/null @@ -1,16 +0,0 @@ -.footer { - font-size: var(--font-size-sm); - text-align: center; - line-height: 30px; - margin: 60px 0; -} - -.footer a { - color: var(--font-color100); -} - -.version { - text-align: right; - padding-right: 10px; - white-space: nowrap; -} diff --git a/components/layout/PageHeader.js b/components/layout/PageHeader.js deleted file mode 100644 index bf243c21..00000000 --- a/components/layout/PageHeader.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import styles from './PageHeader.module.css'; - -export function PageHeader({ title, children }) { - return ( -
-
{title}
-
{children}
-
- ); -} - -export default PageHeader; diff --git a/components/metrics/BarChart.js b/components/metrics/BarChart.js deleted file mode 100644 index cd7070e8..00000000 --- a/components/metrics/BarChart.js +++ /dev/null @@ -1,214 +0,0 @@ -import { useState, useRef, useEffect, useMemo, useCallback } from 'react'; -import { StatusLight, Loading } from 'react-basics'; -import classNames from 'classnames'; -import Chart from 'chart.js/auto'; -import HoverTooltip from 'components/common/HoverTooltip'; -import Legend from 'components/metrics/Legend'; -import { formatLongNumber } from 'lib/format'; -import { dateFormat } from 'lib/date'; -import useLocale from 'hooks/useLocale'; -import useTheme from 'hooks/useTheme'; -import { DEFAULT_ANIMATION_DURATION, THEME_COLORS } from 'lib/constants'; -import styles from './BarChart.module.css'; - -export function BarChart({ - datasets, - unit, - animationDuration = DEFAULT_ANIMATION_DURATION, - stacked = false, - loading = false, - onCreate = () => {}, - onUpdate = () => {}, - className, -}) { - const canvas = useRef(); - const chart = useRef(null); - const [tooltip, setTooltip] = useState(null); - const { locale } = useLocale(); - const [theme] = useTheme(); - - const colors = useMemo( - () => ({ - text: THEME_COLORS[theme].gray700, - line: THEME_COLORS[theme].gray200, - }), - [theme], - ); - - const renderYLabel = label => { - return +label > 1000 ? formatLongNumber(label) : label; - }; - - const renderXLabel = useCallback( - (label, index, values) => { - const d = new Date(values[index].value); - - switch (unit) { - case 'minute': - return dateFormat(d, 'h:mm', locale); - case 'hour': - return dateFormat(d, 'p', locale); - case 'day': - return dateFormat(d, 'MMM d', locale); - case 'month': - return dateFormat(d, 'MMM', locale); - default: - return label; - } - }, - [locale, unit], - ); - - const renderTooltip = useCallback( - model => { - const { opacity, labelColors, dataPoints } = model.tooltip; - - if (!dataPoints?.length || !opacity) { - setTooltip(null); - return; - } - - const formats = { - millisecond: 'T', - second: 'pp', - minute: 'p', - hour: 'h:mm aaa - PP', - day: 'PPPP', - week: 'PPPP', - month: 'LLLL yyyy', - quarter: 'qqq', - year: 'yyyy', - }; - - setTooltip( -
-
{dateFormat(new Date(dataPoints[0].raw.x), formats[unit], locale)}
-
- -
- {formatLongNumber(dataPoints[0].raw.y)} {dataPoints[0].dataset.label} -
-
-
-
, - ); - }, - [unit], - ); - - const getOptions = useCallback(() => { - return { - responsive: true, - maintainAspectRatio: false, - animation: { - duration: animationDuration, - resize: { - duration: 0, - }, - active: { - duration: 0, - }, - }, - plugins: { - legend: { - display: false, - }, - tooltip: { - enabled: false, - external: renderTooltip, - }, - }, - scales: { - x: { - type: 'time', - stacked: true, - time: { - unit, - }, - grid: { - display: false, - }, - border: { - color: colors.line, - }, - ticks: { - color: colors.text, - autoSkip: false, - maxRotation: 0, - callback: renderXLabel, - }, - }, - y: { - type: 'linear', - min: 0, - beginAtZero: true, - stacked, - grid: { - color: colors.line, - }, - border: { - color: colors.line, - }, - ticks: { - color: colors.text, - callback: renderYLabel, - }, - }, - }, - }; - }, [animationDuration, renderTooltip, renderXLabel, stacked, colors, unit, locale]); - - const createChart = () => { - Chart.defaults.font.family = 'Inter'; - - const options = getOptions(); - - chart.current = new Chart(canvas.current, { - type: 'bar', - data: { - datasets, - }, - options, - }); - - onCreate(chart.current); - }; - - const updateChart = () => { - setTooltip(null); - - datasets.forEach((dataset, index) => { - chart.current.data.datasets[index].data = dataset.data; - chart.current.data.datasets[index].label = dataset.label; - }); - - chart.current.options = getOptions(); - - onUpdate(chart.current); - - chart.current.update(); - }; - - useEffect(() => { - if (datasets) { - if (!chart.current) { - createChart(); - } else { - updateChart(); - } - } - }, [datasets, unit, theme, animationDuration, locale]); - - return ( - <> -
- {loading && } - -
- - {tooltip && } - - ); -} - -export default BarChart; diff --git a/components/metrics/CitiesTable.js b/components/metrics/CitiesTable.js deleted file mode 100644 index 2e74780d..00000000 --- a/components/metrics/CitiesTable.js +++ /dev/null @@ -1,32 +0,0 @@ -import MetricsTable from './MetricsTable'; -import { emptyFilter } from 'lib/filters'; -import FilterLink from 'components/common/FilterLink'; -import useLocale from 'hooks/useLocale'; -import useMessages from 'hooks/useMessages'; - -export function CitiesTable({ websiteId, ...props }) { - const { locale } = useLocale(); - const { formatMessage, labels } = useMessages(); - - function renderLink({ x }) { - return ( -
- -
- ); - } - - return ( - - ); -} - -export default CitiesTable; diff --git a/components/metrics/MetricsBar.js b/components/metrics/MetricsBar.js deleted file mode 100644 index 25b93115..00000000 --- a/components/metrics/MetricsBar.js +++ /dev/null @@ -1,115 +0,0 @@ -import { useState } from 'react'; -import { Loading } from 'react-basics'; -import ErrorMessage from 'components/common/ErrorMessage'; -import useApi from 'hooks/useApi'; -import useDateRange from 'hooks/useDateRange'; -import usePageQuery from 'hooks/usePageQuery'; -import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format'; -import MetricCard from './MetricCard'; -import useMessages from 'hooks/useMessages'; -import styles from './MetricsBar.module.css'; - -export function MetricsBar({ websiteId }) { - const { formatMessage, labels } = useMessages(); - const { get, useQuery } = useApi(); - const [dateRange] = useDateRange(websiteId); - const { startDate, endDate, modified } = dateRange; - const [format, setFormat] = useState(true); - const { - query: { url, referrer, os, browser, device, country, region, city }, - } = usePageQuery(); - - const { data, error, isLoading, isFetched } = useQuery( - [ - 'websites:stats', - { websiteId, modified, url, referrer, os, browser, device, country, region, city }, - ], - () => - get(`/websites/${websiteId}/stats`, { - startAt: +startDate, - endAt: +endDate, - url, - referrer, - os, - browser, - device, - country, - region, - city, - }), - ); - - const formatFunc = format - ? n => (n >= 0 ? formatLongNumber(n) : `-${formatLongNumber(Math.abs(n))}`) - : formatNumber; - - function handleSetFormat() { - setFormat(state => !state); - } - - const { pageviews, uniques, bounces, totaltime } = data || {}; - const num = Math.min(data && uniques.value, data && bounces.value); - const diffs = data && { - pageviews: pageviews.value - pageviews.change, - uniques: uniques.value - uniques.change, - bounces: bounces.value - bounces.change, - totaltime: totaltime.value - totaltime.change, - }; - - return ( -
- {isLoading && !isFetched && } - {error && } - {data && !error && isFetched && ( - <> - - - Number(n).toFixed(0) + '%'} - reverseColors - /> - `${n < 0 ? '-' : ''}${formatShortTime(Math.abs(~~n), ['m', 's'], ' ')}`} - /> - - )} -
- ); -} - -export default MetricsBar; diff --git a/components/metrics/PageviewsChart.js b/components/metrics/PageviewsChart.js deleted file mode 100644 index 6ea16226..00000000 --- a/components/metrics/PageviewsChart.js +++ /dev/null @@ -1,64 +0,0 @@ -import { useMemo } from 'react'; -import { colord } from 'colord'; -import BarChart from './BarChart'; -import { THEME_COLORS } from 'lib/constants'; -import useTheme from 'hooks/useTheme'; -import useMessages from 'hooks/useMessages'; -import useLocale from 'hooks/useLocale'; - -export function PageviewsChart({ websiteId, data, unit, records, className, loading, ...props }) { - const { formatMessage, labels } = useMessages(); - const [theme] = useTheme(); - const { locale } = useLocale(); - - const colors = useMemo(() => { - const primaryColor = colord(THEME_COLORS[theme].primary); - return { - views: { - hoverBackgroundColor: primaryColor.alpha(0.7).toRgbString(), - backgroundColor: primaryColor.alpha(0.4).toRgbString(), - borderColor: primaryColor.alpha(0.7).toRgbString(), - hoverBorderColor: primaryColor.toRgbString(), - }, - visitors: { - hoverBackgroundColor: primaryColor.alpha(0.9).toRgbString(), - backgroundColor: primaryColor.alpha(0.6).toRgbString(), - borderColor: primaryColor.alpha(0.9).toRgbString(), - hoverBorderColor: primaryColor.toRgbString(), - }, - }; - }, [theme]); - - const datasets = useMemo(() => { - if (!data) return []; - - return [ - { - label: formatMessage(labels.uniqueVisitors), - data: data.sessions, - borderWidth: 1, - ...colors.visitors, - }, - { - label: formatMessage(labels.pageViews), - data: data.pageviews, - borderWidth: 1, - ...colors.views, - }, - ]; - }, [data, locale, colors]); - - return ( - - ); -} - -export default PageviewsChart; diff --git a/components/metrics/WebsiteChart.js b/components/metrics/WebsiteChart.js deleted file mode 100644 index 6614d40f..00000000 --- a/components/metrics/WebsiteChart.js +++ /dev/null @@ -1,132 +0,0 @@ -import { useMemo } from 'react'; -import { Button, Icon, Text, Row, Column } from 'react-basics'; -import Link from 'next/link'; -import classNames from 'classnames'; -import PageviewsChart from './PageviewsChart'; -import MetricsBar from './MetricsBar'; -import WebsiteHeader from './WebsiteHeader'; -import DateFilter from 'components/input/DateFilter'; -import ErrorMessage from 'components/common/ErrorMessage'; -import FilterTags from 'components/metrics/FilterTags'; -import RefreshButton from 'components/input/RefreshButton'; -import useApi from 'hooks/useApi'; -import useDateRange from 'hooks/useDateRange'; -import useTimezone from 'hooks/useTimezone'; -import usePageQuery from 'hooks/usePageQuery'; -import { getDateArray, getDateLength } from 'lib/date'; -import Icons from 'components/icons'; -import useSticky from 'hooks/useSticky'; -import useMessages from 'hooks/useMessages'; -import styles from './WebsiteChart.module.css'; -import useLocale from 'hooks/useLocale'; - -export function WebsiteChart({ - websiteId, - name, - domain, - stickyHeader = false, - showChart = true, - showDetailsButton = false, - onDataLoad = () => {}, -}) { - const { formatMessage, labels } = useMessages(); - const [dateRange] = useDateRange(websiteId); - const { startDate, endDate, unit, value, modified } = dateRange; - const [timezone] = useTimezone(); - const { - query: { url, referrer, os, browser, device, country, region, city, title }, - } = usePageQuery(); - const { get, useQuery } = useApi(); - const { ref, isSticky } = useSticky({ enabled: stickyHeader }); - - const { data, isLoading, error } = useQuery( - [ - 'websites:pageviews', - { websiteId, modified, url, referrer, os, browser, device, country, region, city, title }, - ], - () => - get(`/websites/${websiteId}/pageviews`, { - startAt: +startDate, - endAt: +endDate, - unit, - timezone, - url, - referrer, - os, - browser, - device, - country, - region, - city, - title, - }), - { onSuccess: onDataLoad }, - ); - - const chartData = useMemo(() => { - if (data) { - return { - pageviews: getDateArray(data.pageviews, startDate, endDate, unit), - sessions: getDateArray(data.sessions, startDate, endDate, unit), - }; - } - return { pageviews: [], sessions: [] }; - }, [data, modified]); - - const { dir } = useLocale(); - return ( - <> - - {showDetailsButton && ( - - - - )} - - - - - - - -
- - -
-
-
- - - {error && } - {showChart && ( - - )} - - - - ); -} - -export default WebsiteChart; diff --git a/components/metrics/WebsiteHeader.js b/components/metrics/WebsiteHeader.js deleted file mode 100644 index de21c0c7..00000000 --- a/components/metrics/WebsiteHeader.js +++ /dev/null @@ -1,21 +0,0 @@ -import { Row, Column, Text } from 'react-basics'; -import Favicon from 'components/common/Favicon'; -import ActiveUsers from './ActiveUsers'; -import styles from './WebsiteHeader.module.css'; - -export function WebsiteHeader({ websiteId, name, domain, children }) { - return ( - - - - {name} - - - - {children} - - - ); -} - -export default WebsiteHeader; diff --git a/components/metrics/WebsiteHeader.module.css b/components/metrics/WebsiteHeader.module.css deleted file mode 100644 index e5ebcca7..00000000 --- a/components/metrics/WebsiteHeader.module.css +++ /dev/null @@ -1,19 +0,0 @@ -.title { - display: flex; - flex-direction: row; - align-items: center; - gap: 10px; - font-size: 24px; - font-weight: 700; - overflow: hidden; - height: 100px; -} - -.info { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-end; - gap: 30px; - min-height: 0; -} diff --git a/components/pages/dashboard/DashboardSettingsButton.js b/components/pages/dashboard/DashboardSettingsButton.js deleted file mode 100644 index a963aa5f..00000000 --- a/components/pages/dashboard/DashboardSettingsButton.js +++ /dev/null @@ -1,46 +0,0 @@ -import { Menu, Icon, Text, PopupTrigger, Popup, Item, Button } from 'react-basics'; -import Icons from 'components/icons'; -import { saveDashboard } from 'store/dashboard'; -import useMessages from 'hooks/useMessages'; - -export function DashboardSettingsButton() { - const { formatMessage, labels } = useMessages(); - - const menuOptions = [ - { - label: formatMessage(labels.toggleCharts), - value: 'charts', - }, - { - label: formatMessage(labels.editDashboard), - value: 'order', - }, - ]; - - function handleSelect(value) { - if (value === 'charts') { - saveDashboard(state => ({ showCharts: !state.showCharts })); - } - if (value === 'order') { - saveDashboard({ editing: true }); - } - } - - return ( - - - - - {({ label, value }) => {label}} - - - - ); -} - -export default DashboardSettingsButton; diff --git a/components/pages/realtime/RealtimeCountries.js b/components/pages/realtime/RealtimeCountries.js deleted file mode 100644 index 525eb28f..00000000 --- a/components/pages/realtime/RealtimeCountries.js +++ /dev/null @@ -1,27 +0,0 @@ -import { useCallback } from 'react'; -import DataTable from 'components/metrics/DataTable'; -import useLocale from 'hooks/useLocale'; -import useCountryNames from 'hooks/useCountryNames'; -import useMessages from 'hooks/useMessages'; - -export function RealtimeCountries({ data }) { - const { formatMessage, labels } = useMessages(); - const { locale } = useLocale(); - const countryNames = useCountryNames(locale); - - const renderCountryName = useCallback( - ({ x }) => {countryNames[x]}, - [countryNames, locale], - ); - - return ( - - ); -} - -export default RealtimeCountries; diff --git a/components/pages/settings/teams/TeamMembers.js b/components/pages/settings/teams/TeamMembers.js deleted file mode 100644 index 333e176d..00000000 --- a/components/pages/settings/teams/TeamMembers.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Loading, useToast } from 'react-basics'; -import TeamMembersTable from 'components/pages/settings/teams/TeamMembersTable'; -import useApi from 'hooks/useApi'; -import useMessages from 'hooks/useMessages'; - -export function TeamMembers({ teamId, readOnly }) { - const { toast, showToast } = useToast(); - const { get, useQuery } = useApi(); - const { formatMessage, messages } = useMessages(); - const { data, isLoading, refetch } = useQuery(['teams:users', teamId], () => - get(`/teams/${teamId}/users`), - ); - - if (isLoading) { - return ; - } - - const handleSave = async () => { - await refetch(); - showToast({ message: formatMessage(messages.saved), variant: 'success' }); - }; - - return ( - <> - {toast} - - - ); -} - -export default TeamMembers; diff --git a/components/pages/settings/users/UserWebsites.js b/components/pages/settings/users/UserWebsites.js deleted file mode 100644 index 144fae44..00000000 --- a/components/pages/settings/users/UserWebsites.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Loading } from 'react-basics'; -import useApi from 'hooks/useApi'; -import WebsitesTable from 'components/pages/settings/websites/WebsitesTable'; -import useMessages from 'hooks/useMessages'; - -export function UserWebsites({ userId }) { - const { formatMessage, messages } = useMessages(); - const { get, useQuery } = useApi(); - const { data, isLoading } = useQuery(['user:websites', userId], () => - get(`/users/${userId}/websites`), - ); - const hasData = data && data.length !== 0; - - if (isLoading) { - return ; - } - - return ( -
- {hasData && } - {!hasData && formatMessage(messages.noDataAvailable)} -
- ); -} - -export default UserWebsites; diff --git a/components/pages/settings/websites/WebsitesList.js b/components/pages/settings/websites/WebsitesList.js deleted file mode 100644 index 84f96c83..00000000 --- a/components/pages/settings/websites/WebsitesList.js +++ /dev/null @@ -1,56 +0,0 @@ -import { Button, Icon, Text, Modal, ModalTrigger, useToast, Icons } from 'react-basics'; -import Page from 'components/layout/Page'; -import PageHeader from 'components/layout/PageHeader'; -import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; -import WebsiteAddForm from 'components/pages/settings/websites/WebsiteAddForm'; -import WebsitesTable from 'components/pages/settings/websites/WebsitesTable'; -import useApi from 'hooks/useApi'; -import useUser from 'hooks/useUser'; -import useMessages from 'hooks/useMessages'; - -export function WebsitesList() { - const { formatMessage, labels, messages } = useMessages(); - const { user } = useUser(); - const { get, useQuery } = useApi(); - const { data, isLoading, error, refetch } = useQuery( - ['websites', user?.id], - () => get(`/users/${user?.id}/websites`), - { enabled: !!user }, - ); - const { toast, showToast } = useToast(); - const hasData = data && data.length !== 0; - - const handleSave = async () => { - await refetch(); - showToast({ message: formatMessage(messages.saved), variant: 'success' }); - }; - - const addButton = ( - - - - {close => } - - - ); - - return ( - - {toast} - {addButton} - {hasData && } - {!hasData && ( - - {addButton} - - )} - - ); -} - -export default WebsitesList; diff --git a/components/pages/settings/websites/WebsitesTable.js b/components/pages/settings/websites/WebsitesTable.js deleted file mode 100644 index 902393e6..00000000 --- a/components/pages/settings/websites/WebsitesTable.js +++ /dev/null @@ -1,47 +0,0 @@ -import Link from 'next/link'; -import { Button, Text, Icon, Icons } from 'react-basics'; -import SettingsTable from 'components/common/SettingsTable'; -import useMessages from 'hooks/useMessages'; -import useConfig from 'hooks/useConfig'; - -export function WebsitesTable({ data = [] }) { - const { formatMessage, labels } = useMessages(); - const { openExternal } = useConfig(); - - const columns = [ - { name: 'name', label: formatMessage(labels.name) }, - { name: 'domain', label: formatMessage(labels.domain) }, - { name: 'action', label: ' ' }, - ]; - - return ( - - {row => { - const { id } = row; - - return ( - <> - - - - - - - - ); - }} - - ); -} - -export default WebsitesTable; diff --git a/components/pages/websites/WebsiteChartList.js b/components/pages/websites/WebsiteChartList.js deleted file mode 100644 index 0c552704..00000000 --- a/components/pages/websites/WebsiteChartList.js +++ /dev/null @@ -1,35 +0,0 @@ -import { useMemo } from 'react'; -import { firstBy } from 'thenby'; -import WebsiteChart from 'components/metrics/WebsiteChart'; -import useDashboard from 'store/dashboard'; -import styles from './WebsiteList.module.css'; - -export default function WebsiteChartList({ websites, showCharts, limit }) { - const { websiteOrder } = useDashboard(); - - const ordered = useMemo( - () => - websites - .map(website => ({ ...website, order: websiteOrder.indexOf(website.id) || 0 })) - .sort(firstBy('order')), - [websites, websiteOrder], - ); - - return ( -
- {ordered.map(({ id, name, domain }, index) => { - return index < limit ? ( -
- -
- ) : null; - })} -
- ); -} diff --git a/components/pages/websites/WebsiteDetails.js b/components/pages/websites/WebsiteDetails.js deleted file mode 100644 index ba80bcf8..00000000 --- a/components/pages/websites/WebsiteDetails.js +++ /dev/null @@ -1,47 +0,0 @@ -import { useState } from 'react'; -import { Loading } from 'react-basics'; -import Page from 'components/layout/Page'; -import WebsiteChart from 'components/metrics/WebsiteChart'; -import useApi from 'hooks/useApi'; -import usePageQuery from 'hooks/usePageQuery'; -import { DEFAULT_ANIMATION_DURATION } from 'lib/constants'; -import WebsiteTableView from './WebsiteTableView'; -import WebsiteMenuView from './WebsiteMenuView'; - -export default function WebsiteDetails({ websiteId }) { - const { get, useQuery } = useApi(); - const { data, isLoading, error } = useQuery(['websites', websiteId], () => - get(`/websites/${websiteId}`), - ); - const [chartLoaded, setChartLoaded] = useState(false); - - const { - query: { view }, - } = usePageQuery(); - - function handleDataLoad() { - if (!chartLoaded) { - setTimeout(() => setChartLoaded(true), DEFAULT_ANIMATION_DURATION); - } - } - - return ( - - - {!chartLoaded && } - {chartLoaded && ( - <> - {!view && } - {view && } - - )} - - ); -} diff --git a/components/pages/websites/WebsiteDetails.module.css b/components/pages/websites/WebsiteDetails.module.css deleted file mode 100644 index b0632be6..00000000 --- a/components/pages/websites/WebsiteDetails.module.css +++ /dev/null @@ -1,31 +0,0 @@ -.chart { - margin-bottom: 30px; -} - -.view { - border-top: 1px solid var(--base300); -} - -.menu { - font-size: var(--font-size-sm); -} - -.content { - min-height: 600px; - padding: 20px 0; -} - -.backButton { - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 16px; -} - -.backButton svg { - transform: rotate(180deg); -} - -.hidden { - display: none; -} diff --git a/db/clickhouse/migrations/01_edit_keys.sql b/db/clickhouse/migrations/01_edit_keys.sql new file mode 100644 index 00000000..3fc7dd79 --- /dev/null +++ b/db/clickhouse/migrations/01_edit_keys.sql @@ -0,0 +1,18 @@ +-- edit event_data values +ALTER TABLE "event_data" RENAME COLUMN "event_date_value" TO "date_value"; +ALTER TABLE "event_data" RENAME COLUMN "event_numeric_value" TO "number_value"; +ALTER TABLE "event_data" RENAME COLUMN "event_string_value" TO "string_value"; +ALTER TABLE "event_data" RENAME COLUMN "event_data_type" TO "data_type"; + +-- add job_id +ALTER TABLE "website_event" ADD COLUMN "job_id" UUID AFTER "created_at"; +ALTER TABLE "event_data" ADD COLUMN "job_id" UUID AFTER "created_at"; + +-- update event_data string +alter table umami.event_data +update string_value = number_value +where data_type = 2 + +alter table umami.event_data +update string_value = replaceOne(concat(CAST(toDateTime(date_value, 'UTC'), 'String'),'Z'), ' ', 'T') +where data_type = 4 \ No newline at end of file diff --git a/db/clickhouse/schema.sql b/db/clickhouse/schema.sql index 77176413..94b560c3 100644 --- a/db/clickhouse/schema.sql +++ b/db/clickhouse/schema.sql @@ -6,7 +6,7 @@ CREATE TABLE umami.website_event website_id UUID, session_id UUID, event_id UUID, - --session + --sessions hostname LowCardinality(String), browser LowCardinality(String), os LowCardinality(String), @@ -17,17 +17,18 @@ CREATE TABLE umami.website_event subdivision1 LowCardinality(String), subdivision2 LowCardinality(String), city String, - --pageview + --pageviews url_path String, url_query String, referrer_path String, referrer_query String, referrer_domain String, page_title String, - --event + --events event_type UInt32, event_name String, - created_at DateTime('UTC') + created_at DateTime('UTC'), + job_id UUID ) engine = MergeTree ORDER BY (website_id, session_id, created_at) @@ -37,7 +38,7 @@ CREATE TABLE umami.website_event_queue ( website_id UUID, session_id UUID, event_id UUID, - --session + --sessions hostname LowCardinality(String), browser LowCardinality(String), os LowCardinality(String), @@ -48,25 +49,28 @@ CREATE TABLE umami.website_event_queue ( subdivision1 LowCardinality(String), subdivision2 LowCardinality(String), city String, - --pageview + --pageviews url_path String, url_query String, referrer_path String, referrer_query String, referrer_domain String, page_title String, - --event + --events event_type UInt32, event_name String, - created_at DateTime('UTC') + created_at DateTime('UTC'), + --virtual columns + _error String, + _raw_message String ) ENGINE = Kafka SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input broker list - kafka_topic_list = 'event', + kafka_topic_list = 'events', kafka_group_name = 'event_consumer_group', kafka_format = 'JSONEachRow', kafka_max_block_size = 1048576, - kafka_skip_broken_messages = 100; + kafka_handle_error_mode = 'stream'; CREATE MATERIALIZED VIEW umami.website_event_queue_mv TO umami.website_event AS SELECT website_id, @@ -93,6 +97,19 @@ SELECT website_id, created_at FROM umami.website_event_queue; +CREATE MATERIALIZED VIEW umami.website_event_errors_mv +( + error String, + raw String +) +ENGINE = MergeTree +ORDER BY (error, raw) +SETTINGS index_granularity = 8192 AS +SELECT _error AS error, + _raw_message AS raw +FROM umami.website_event_queue +WHERE length(_error) > 0; + CREATE TABLE umami.event_data ( website_id UUID, @@ -101,11 +118,12 @@ CREATE TABLE umami.event_data url_path String, event_name String, event_key String, - event_string_value Nullable(String), - event_numeric_value Nullable(Decimal64(4)), --922337203685477.5625 - event_date_value Nullable(DateTime('UTC')), - event_data_type UInt32, - created_at DateTime('UTC') + string_value Nullable(String), + number_value Nullable(Decimal64(4)), --922337203685477.5625 + date_value Nullable(DateTime('UTC')), + data_type UInt32, + created_at DateTime('UTC'), + job_id UUID ) engine = MergeTree ORDER BY (website_id, event_id, event_key, created_at) @@ -118,11 +136,14 @@ CREATE TABLE umami.event_data_queue ( url_path String, event_name String, event_key String, - event_string_value Nullable(String), - event_numeric_value Nullable(Decimal64(4)), --922337203685477.5625 - event_date_value Nullable(DateTime('UTC')), - event_data_type UInt32, - created_at DateTime('UTC') + string_value Nullable(String), + number_value Nullable(Decimal64(4)), --922337203685477.5625 + date_value Nullable(DateTime('UTC')), + data_type UInt32, + created_at DateTime('UTC'), + --virtual columns + _error String, + _raw_message String ) ENGINE = Kafka SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input broker list @@ -130,7 +151,7 @@ SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input bro kafka_group_name = 'event_data_consumer_group', kafka_format = 'JSONEachRow', kafka_max_block_size = 1048576, - kafka_skip_broken_messages = 100; + kafka_handle_error_mode = 'stream'; CREATE MATERIALIZED VIEW umami.event_data_queue_mv TO umami.event_data AS SELECT website_id, @@ -139,9 +160,22 @@ SELECT website_id, url_path, event_name, event_key, - event_string_value, - event_numeric_value, - event_date_value, - event_data_type, + string_value, + number_value, + date_value, + data_type, created_at -FROM umami.event_data_queue; \ No newline at end of file +FROM umami.event_data_queue; + +CREATE MATERIALIZED VIEW umami.event_data_errors_mv +( + error String, + raw String +) +ENGINE = MergeTree +ORDER BY (error, raw) +SETTINGS index_granularity = 8192 AS +SELECT _error AS error, + _raw_message AS raw +FROM umami.event_data_queue +WHERE length(_error) > 0; \ No newline at end of file diff --git a/db/mysql/migrations/02_report_schema_session_data/migration.sql b/db/mysql/migrations/02_report_schema_session_data/migration.sql new file mode 100644 index 00000000..49708899 --- /dev/null +++ b/db/mysql/migrations/02_report_schema_session_data/migration.sql @@ -0,0 +1,53 @@ +-- AlterTable +ALTER TABLE `event_data` RENAME COLUMN `event_data_type` TO `data_type`; +ALTER TABLE `event_data` RENAME COLUMN `event_date_value` TO `date_value`; +ALTER TABLE `event_data` RENAME COLUMN `event_id` TO `event_data_id`; +ALTER TABLE `event_data` RENAME COLUMN `event_numeric_value` TO `number_value`; +ALTER TABLE `event_data` RENAME COLUMN `event_string_value` TO `string_value`; + +-- CreateTable +CREATE TABLE `session_data` ( + `session_data_id` VARCHAR(36) NOT NULL, + `website_id` VARCHAR(36) NOT NULL, + `session_id` VARCHAR(36) NOT NULL, + `event_key` VARCHAR(500) NOT NULL, + `string_value` VARCHAR(500) NULL, + `number_value` DECIMAL(19, 4) NULL, + `date_value` TIMESTAMP(0) NULL, + `data_type` INTEGER UNSIGNED NOT NULL, + `created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + + INDEX `session_data_created_at_idx`(`created_at`), + INDEX `session_data_website_id_idx`(`website_id`), + INDEX `session_data_session_id_idx`(`session_id`), + PRIMARY KEY (`session_data_id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `report` ( + `report_id` VARCHAR(36) NOT NULL, + `user_id` VARCHAR(36) NOT NULL, + `website_id` VARCHAR(36) NOT NULL, + `type` VARCHAR(200) NOT NULL, + `name` VARCHAR(200) NOT NULL, + `description` VARCHAR(500) NOT NULL, + `parameters` VARCHAR(6000) NOT NULL, + `created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0), + `updated_at` TIMESTAMP(0) NULL, + + UNIQUE INDEX `report_report_id_key`(`report_id`), + INDEX `report_user_id_idx`(`user_id`), + INDEX `report_website_id_idx`(`website_id`), + INDEX `report_type_idx`(`type`), + INDEX `report_name_idx`(`name`), + PRIMARY KEY (`report_id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- EventData migration +UPDATE event_data +SET string_value = number_value +WHERE data_type = 2; + +UPDATE event_data +SET string_value = CONCAT(REPLACE(DATE_FORMAT(date_value, '%Y-%m-%d %T'), ' ', 'T'), 'Z') +WHERE data_type = 4; \ No newline at end of file diff --git a/db/mysql/migrations/03_metric_performance_index/migration.sql b/db/mysql/migrations/03_metric_performance_index/migration.sql new file mode 100644 index 00000000..64681364 --- /dev/null +++ b/db/mysql/migrations/03_metric_performance_index/migration.sql @@ -0,0 +1,50 @@ +-- CreateIndex +CREATE INDEX `event_data_website_id_created_at_idx` ON `event_data`(`website_id`, `created_at`); + +-- CreateIndex +CREATE INDEX `event_data_website_id_created_at_event_key_idx` ON `event_data`(`website_id`, `created_at`, `event_key`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_idx` ON `session`(`website_id`, `created_at`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_hostname_idx` ON `session`(`website_id`, `created_at`, `hostname`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_browser_idx` ON `session`(`website_id`, `created_at`, `browser`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_os_idx` ON `session`(`website_id`, `created_at`, `os`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_device_idx` ON `session`(`website_id`, `created_at`, `device`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_screen_idx` ON `session`(`website_id`, `created_at`, `screen`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_language_idx` ON `session`(`website_id`, `created_at`, `language`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_country_idx` ON `session`(`website_id`, `created_at`, `country`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_subdivision1_idx` ON `session`(`website_id`, `created_at`, `subdivision1`); + +-- CreateIndex +CREATE INDEX `session_website_id_created_at_city_idx` ON `session`(`website_id`, `created_at`, `city`); + +-- CreateIndex +CREATE INDEX `website_event_website_id_created_at_url_path_idx` ON `website_event`(`website_id`, `created_at`, `url_path`); + +-- CreateIndex +CREATE INDEX `website_event_website_id_created_at_url_query_idx` ON `website_event`(`website_id`, `created_at`, `url_query`); + +-- CreateIndex +CREATE INDEX `website_event_website_id_created_at_referrer_domain_idx` ON `website_event`(`website_id`, `created_at`, `referrer_domain`); + +-- CreateIndex +CREATE INDEX `website_event_website_id_created_at_page_title_idx` ON `website_event`(`website_id`, `created_at`, `page_title`); + +-- CreateIndex +CREATE INDEX `website_event_website_id_created_at_event_name_idx` ON `website_event`(`website_id`, `created_at`, `event_name`); diff --git a/db/mysql/schema.prisma b/db/mysql/schema.prisma index 6455c8c0..38bb91f4 100644 --- a/db/mysql/schema.prisma +++ b/db/mysql/schema.prisma @@ -14,11 +14,12 @@ model User { password String @db.VarChar(60) role String @map("role") @db.VarChar(50) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0) deletedAt DateTime? @map("deleted_at") @db.Timestamp(0) website Website[] teamUser TeamUser[] + report Report[] @@map("user") } @@ -39,9 +40,20 @@ model Session { createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) websiteEvent WebsiteEvent[] + sessionData SessionData[] @@index([createdAt]) @@index([websiteId]) + @@index([websiteId, createdAt]) + @@index([websiteId, createdAt, hostname]) + @@index([websiteId, createdAt, browser]) + @@index([websiteId, createdAt, os]) + @@index([websiteId, createdAt, device]) + @@index([websiteId, createdAt, screen]) + @@index([websiteId, createdAt, language]) + @@index([websiteId, createdAt, country]) + @@index([websiteId, createdAt, subdivision1]) + @@index([websiteId, createdAt, city]) @@map("session") } @@ -53,12 +65,14 @@ model Website { resetAt DateTime? @map("reset_at") @db.Timestamp(0) userId String? @map("user_id") @db.VarChar(36) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0) deletedAt DateTime? @map("deleted_at") @db.Timestamp(0) user User? @relation(fields: [userId], references: [id]) teamWebsite TeamWebsite[] eventData EventData[] + report Report[] + sessionData SessionData[] @@index([userId]) @@index([createdAt]) @@ -87,20 +101,25 @@ model WebsiteEvent { @@index([sessionId]) @@index([websiteId]) @@index([websiteId, createdAt]) + @@index([websiteId, createdAt, urlPath]) + @@index([websiteId, createdAt, urlQuery]) + @@index([websiteId, createdAt, referrerDomain]) + @@index([websiteId, createdAt, pageTitle]) + @@index([websiteId, createdAt, eventName]) @@index([websiteId, sessionId, createdAt]) @@map("website_event") } model EventData { - id String @id() @map("event_id") @db.VarChar(36) - websiteEventId String @map("website_event_id") @db.VarChar(36) - websiteId String @map("website_id") @db.VarChar(36) - eventKey String @map("event_key") @db.VarChar(500) - eventStringValue String? @map("event_string_value") @db.VarChar(500) - eventNumericValue Decimal? @map("event_numeric_value") @db.Decimal(19, 4) - eventDateValue DateTime? @map("event_date_value") @db.Timestamp(0) - eventDataType Int @map("event_data_type") @db.UnsignedInt - createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) + id String @id() @map("event_data_id") @db.VarChar(36) + websiteId String @map("website_id") @db.VarChar(36) + websiteEventId String @map("website_event_id") @db.VarChar(36) + eventKey String @map("event_key") @db.VarChar(500) + stringValue String? @map("string_value") @db.VarChar(500) + numberValue Decimal? @map("number_value") @db.Decimal(19, 4) + dateValue DateTime? @map("date_value") @db.Timestamp(0) + dataType Int @map("data_type") @db.UnsignedInt + createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) website Website @relation(fields: [websiteId], references: [id]) websiteEvent WebsiteEvent @relation(fields: [websiteEventId], references: [id]) @@ -109,15 +128,37 @@ model EventData { @@index([websiteId]) @@index([websiteEventId]) @@index([websiteId, websiteEventId, createdAt]) + @@index([websiteId, createdAt]) + @@index([websiteId, createdAt, eventKey]) @@map("event_data") } +model SessionData { + id String @id() @map("session_data_id") @db.VarChar(36) + websiteId String @map("website_id") @db.VarChar(36) + sessionId String @map("session_id") @db.VarChar(36) + eventKey String @map("event_key") @db.VarChar(500) + stringValue String? @map("string_value") @db.VarChar(500) + numberValue Decimal? @map("number_value") @db.Decimal(19, 4) + dateValue DateTime? @map("date_value") @db.Timestamp(0) + dataType Int @map("data_type") @db.UnsignedInt + createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) + + website Website @relation(fields: [websiteId], references: [id]) + session Session @relation(fields: [sessionId], references: [id]) + + @@index([createdAt]) + @@index([websiteId]) + @@index([sessionId]) + @@map("session_data") +} + model Team { id String @id() @unique() @map("team_id") @db.VarChar(36) name String @db.VarChar(50) accessCode String? @unique @map("access_code") @db.VarChar(50) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0) teamUser TeamUser[] teamWebsite TeamWebsite[] @@ -132,7 +173,7 @@ model TeamUser { userId String @map("user_id") @db.VarChar(36) role String @map("role") @db.VarChar(50) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamp(0) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0) team Team @relation(fields: [teamId], references: [id]) user User @relation(fields: [userId], references: [id]) @@ -155,3 +196,24 @@ model TeamWebsite { @@index([websiteId]) @@map("team_website") } + +model Report { + id String @id() @unique() @map("report_id") @db.VarChar(36) + userId String @map("user_id") @db.VarChar(36) + websiteId String @map("website_id") @db.VarChar(36) + type String @map("type") @db.VarChar(200) + name String @map("name") @db.VarChar(200) + description String @map("description") @db.VarChar(500) + parameters String @map("parameters") @db.VarChar(6000) + createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamp(0) + + user User @relation(fields: [userId], references: [id]) + website Website @relation(fields: [websiteId], references: [id]) + + @@index([userId]) + @@index([websiteId]) + @@index([type]) + @@index([name]) + @@map("report") +} diff --git a/db/postgresql/migrations/02_report_schema_session_data/migration.sql b/db/postgresql/migrations/02_report_schema_session_data/migration.sql new file mode 100644 index 00000000..5fe6ef9d --- /dev/null +++ b/db/postgresql/migrations/02_report_schema_session_data/migration.sql @@ -0,0 +1,70 @@ +-- AlterTable +ALTER TABLE "event_data" RENAME COLUMN "event_data_type" TO "data_type"; +ALTER TABLE "event_data" RENAME COLUMN "event_date_value" TO "date_value"; +ALTER TABLE "event_data" RENAME COLUMN "event_id" TO "event_data_id"; +ALTER TABLE "event_data" RENAME COLUMN "event_numeric_value" TO "number_value"; +ALTER TABLE "event_data" RENAME COLUMN "event_string_value" TO "string_value"; + +-- CreateTable +CREATE TABLE "session_data" ( + "session_data_id" UUID NOT NULL, + "website_id" UUID NOT NULL, + "session_id" UUID NOT NULL, + "session_key" VARCHAR(500) NOT NULL, + "string_value" VARCHAR(500), + "number_value" DECIMAL(19,4), + "date_value" TIMESTAMPTZ(6), + "data_type" INTEGER NOT NULL, + "created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP, + "deleted_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "session_data_pkey" PRIMARY KEY ("session_data_id") +); + +-- CreateTable +CREATE TABLE "report" ( + "report_id" UUID NOT NULL, + "user_id" UUID NOT NULL, + "website_id" UUID NOT NULL, + "type" VARCHAR(200) NOT NULL, + "name" VARCHAR(200) NOT NULL, + "description" VARCHAR(500) NOT NULL, + "parameters" VARCHAR(6000) NOT NULL, + "created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMPTZ(6), + + CONSTRAINT "report_pkey" PRIMARY KEY ("report_id") +); + +-- CreateIndex +CREATE INDEX "session_data_created_at_idx" ON "session_data"("created_at"); + +-- CreateIndex +CREATE INDEX "session_data_website_id_idx" ON "session_data"("website_id"); + +-- CreateIndex +CREATE INDEX "session_data_session_id_idx" ON "session_data"("session_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "report_report_id_key" ON "report"("report_id"); + +-- CreateIndex +CREATE INDEX "report_user_id_idx" ON "report"("user_id"); + +-- CreateIndex +CREATE INDEX "report_website_id_idx" ON "report"("website_id"); + +-- CreateIndex +CREATE INDEX "report_type_idx" ON "report"("type"); + +-- CreateIndex +CREATE INDEX "report_name_idx" ON "report"("name"); + +-- EventData migration +UPDATE "event_data" +SET string_value = number_value +WHERE data_type = 2; + +UPDATE "event_data" +SET string_value = CONCAT(REPLACE(TO_CHAR(date_value, 'YYYY-MM-DD HH24:MI:SS'), ' ', 'T'), 'Z') +WHERE data_type = 4; \ No newline at end of file diff --git a/db/postgresql/migrations/03_metric_performance_index/migration.sql b/db/postgresql/migrations/03_metric_performance_index/migration.sql new file mode 100644 index 00000000..5db7aa50 --- /dev/null +++ b/db/postgresql/migrations/03_metric_performance_index/migration.sql @@ -0,0 +1,50 @@ +-- CreateIndex +CREATE INDEX "event_data_website_id_created_at_idx" ON "event_data"("website_id", "created_at"); + +-- CreateIndex +CREATE INDEX "event_data_website_id_created_at_event_key_idx" ON "event_data"("website_id", "created_at", "event_key"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_idx" ON "session"("website_id", "created_at"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_hostname_idx" ON "session"("website_id", "created_at", "hostname"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_browser_idx" ON "session"("website_id", "created_at", "browser"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_os_idx" ON "session"("website_id", "created_at", "os"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_device_idx" ON "session"("website_id", "created_at", "device"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_screen_idx" ON "session"("website_id", "created_at", "screen"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_language_idx" ON "session"("website_id", "created_at", "language"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_country_idx" ON "session"("website_id", "created_at", "country"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_subdivision1_idx" ON "session"("website_id", "created_at", "subdivision1"); + +-- CreateIndex +CREATE INDEX "session_website_id_created_at_city_idx" ON "session"("website_id", "created_at", "city"); + +-- CreateIndex +CREATE INDEX "website_event_website_id_created_at_url_path_idx" ON "website_event"("website_id", "created_at", "url_path"); + +-- CreateIndex +CREATE INDEX "website_event_website_id_created_at_url_query_idx" ON "website_event"("website_id", "created_at", "url_query"); + +-- CreateIndex +CREATE INDEX "website_event_website_id_created_at_referrer_domain_idx" ON "website_event"("website_id", "created_at", "referrer_domain"); + +-- CreateIndex +CREATE INDEX "website_event_website_id_created_at_page_title_idx" ON "website_event"("website_id", "created_at", "page_title"); + +-- CreateIndex +CREATE INDEX "website_event_website_id_created_at_event_name_idx" ON "website_event"("website_id", "created_at", "event_name"); diff --git a/db/postgresql/schema.prisma b/db/postgresql/schema.prisma index b336bce4..d7a70ab0 100644 --- a/db/postgresql/schema.prisma +++ b/db/postgresql/schema.prisma @@ -14,11 +14,12 @@ model User { password String @db.VarChar(60) role String @map("role") @db.VarChar(50) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6) deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6) website Website[] teamUser TeamUser[] + report Report[] @@map("user") } @@ -39,9 +40,20 @@ model Session { createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) websiteEvent WebsiteEvent[] + sessionData SessionData[] @@index([createdAt]) @@index([websiteId]) + @@index([websiteId, createdAt]) + @@index([websiteId, createdAt, hostname]) + @@index([websiteId, createdAt, browser]) + @@index([websiteId, createdAt, os]) + @@index([websiteId, createdAt, device]) + @@index([websiteId, createdAt, screen]) + @@index([websiteId, createdAt, language]) + @@index([websiteId, createdAt, country]) + @@index([websiteId, createdAt, subdivision1]) + @@index([websiteId, createdAt, city]) @@map("session") } @@ -53,12 +65,14 @@ model Website { resetAt DateTime? @map("reset_at") @db.Timestamptz(6) userId String? @map("user_id") @db.Uuid createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6) deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6) user User? @relation(fields: [userId], references: [id]) teamWebsite TeamWebsite[] eventData EventData[] + report Report[] + sessionData SessionData[] @@index([userId]) @@index([createdAt]) @@ -87,20 +101,25 @@ model WebsiteEvent { @@index([sessionId]) @@index([websiteId]) @@index([websiteId, createdAt]) + @@index([websiteId, createdAt, urlPath]) + @@index([websiteId, createdAt, urlQuery]) + @@index([websiteId, createdAt, referrerDomain]) + @@index([websiteId, createdAt, pageTitle]) + @@index([websiteId, createdAt, eventName]) @@index([websiteId, sessionId, createdAt]) @@map("website_event") } model EventData { - id String @id() @map("event_id") @db.Uuid - websiteId String @map("website_id") @db.Uuid - websiteEventId String @map("website_event_id") @db.Uuid - eventKey String @map("event_key") @db.VarChar(500) - eventStringValue String? @map("event_string_value") @db.VarChar(500) - eventNumericValue Decimal? @map("event_numeric_value") @db.Decimal(19, 4) - eventDateValue DateTime? @map("event_date_value") @db.Timestamptz(6) - eventDataType Int @map("event_data_type") @db.Integer - createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) + id String @id() @map("event_data_id") @db.Uuid + websiteId String @map("website_id") @db.Uuid + websiteEventId String @map("website_event_id") @db.Uuid + eventKey String @map("event_key") @db.VarChar(500) + stringValue String? @map("string_value") @db.VarChar(500) + numberValue Decimal? @map("number_value") @db.Decimal(19, 4) + dateValue DateTime? @map("date_value") @db.Timestamptz(6) + dataType Int @map("data_type") @db.Integer + createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) website Website @relation(fields: [websiteId], references: [id]) websiteEvent WebsiteEvent @relation(fields: [websiteEventId], references: [id]) @@ -108,15 +127,38 @@ model EventData { @@index([createdAt]) @@index([websiteId]) @@index([websiteEventId]) + @@index([websiteId, createdAt]) + @@index([websiteId, createdAt, eventKey]) @@map("event_data") } +model SessionData { + id String @id() @map("session_data_id") @db.Uuid + websiteId String @map("website_id") @db.Uuid + sessionId String @map("session_id") @db.Uuid + sessionKey String @map("session_key") @db.VarChar(500) + stringValue String? @map("string_value") @db.VarChar(500) + numberValue Decimal? @map("number_value") @db.Decimal(19, 4) + dateValue DateTime? @map("date_value") @db.Timestamptz(6) + dataType Int @map("data_type") @db.Integer + createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) + deletedAt DateTime? @default(now()) @map("deleted_at") @db.Timestamptz(6) + + website Website @relation(fields: [websiteId], references: [id]) + session Session @relation(fields: [sessionId], references: [id]) + + @@index([createdAt]) + @@index([websiteId]) + @@index([sessionId]) + @@map("session_data") +} + model Team { id String @id() @unique() @map("team_id") @db.Uuid name String @db.VarChar(50) accessCode String? @unique @map("access_code") @db.VarChar(50) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6) teamUser TeamUser[] teamWebsite TeamWebsite[] @@ -131,7 +173,7 @@ model TeamUser { userId String @map("user_id") @db.Uuid role String @map("role") @db.VarChar(50) createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) - updatedAt DateTime? @map("updated_at") @updatedAt @db.Timestamptz(6) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6) team Team @relation(fields: [teamId], references: [id]) user User @relation(fields: [userId], references: [id]) @@ -154,3 +196,24 @@ model TeamWebsite { @@index([websiteId]) @@map("team_website") } + +model Report { + id String @id() @unique() @map("report_id") @db.Uuid + userId String @map("user_id") @db.Uuid + websiteId String @map("website_id") @db.Uuid + type String @map("type") @db.VarChar(200) + name String @map("name") @db.VarChar(200) + description String @map("description") @db.VarChar(500) + parameters String @map("parameters") @db.VarChar(6000) + createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6) + updatedAt DateTime? @updatedAt @map("updated_at") @db.Timestamptz(6) + + user User @relation(fields: [userId], references: [id]) + website Website @relation(fields: [websiteId], references: [id]) + + @@index([userId]) + @@index([websiteId]) + @@index([type]) + @@index([name]) + @@map("report") +} diff --git a/docker-compose.yml b/docker-compose.yml index bd63c68b..b8da9373 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,8 @@ services: DATABASE_TYPE: postgresql APP_SECRET: replace-me-with-a-random-string depends_on: - - db + db: + condition: service_healthy restart: always db: image: postgres:15-alpine @@ -19,8 +20,12 @@ services: POSTGRES_USER: umami POSTGRES_PASSWORD: umami volumes: - - ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro - umami-db-data:/var/lib/postgresql/data restart: always + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 5s + retries: 5 volumes: umami-db-data: diff --git a/hooks/useDateRange.js b/hooks/useDateRange.js deleted file mode 100644 index a9896065..00000000 --- a/hooks/useDateRange.js +++ /dev/null @@ -1,25 +0,0 @@ -import { parseDateRange } from 'lib/date'; -import { setItem } from 'next-basics'; -import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE } from 'lib/constants'; -import useLocale from './useLocale'; -import websiteStore, { setWebsiteDateRange } from 'store/websites'; -import appStore, { setDateRange } from 'store/app'; - -export default function useDateRange(websiteId) { - const { locale } = useLocale(); - const websiteConfig = websiteStore(state => state[websiteId]?.dateRange); - const defaultConfig = DEFAULT_DATE_RANGE; - const globalConfig = appStore(state => state.dateRange); - const dateRange = parseDateRange(websiteConfig || globalConfig || defaultConfig, locale); - - function saveDateRange(value) { - if (websiteId) { - setWebsiteDateRange(websiteId, value); - } else { - setItem(DATE_RANGE_CONFIG, value); - setDateRange(value); - } - } - - return [dateRange, saveDateRange]; -} diff --git a/hooks/useTheme.js b/hooks/useTheme.js deleted file mode 100644 index c50f442f..00000000 --- a/hooks/useTheme.js +++ /dev/null @@ -1,36 +0,0 @@ -import { useEffect } from 'react'; -import useStore, { setTheme } from 'store/app'; -import { getItem, setItem } from 'next-basics'; -import { THEME_CONFIG } from 'lib/constants'; - -const selector = state => state.theme; - -export default function useTheme() { - const defaultTheme = - typeof window !== 'undefined' - ? window?.matchMedia('(prefers-color-scheme: dark)')?.matches - ? 'dark' - : 'light' - : 'light'; - const theme = useStore(selector) || getItem(THEME_CONFIG) || defaultTheme; - - function saveTheme(value) { - setItem(THEME_CONFIG, value); - setTheme(value); - } - - useEffect(() => { - document.body.setAttribute('data-theme', theme); - }, [theme]); - - useEffect(() => { - const url = new URL(window?.location?.href); - const theme = url.searchParams.get('theme'); - - if (['light', 'dark'].includes(theme)) { - saveTheme(theme); - } - }, []); - - return [theme, saveTheme]; -} diff --git a/jsconfig.json b/jsconfig.json index b639b0f8..738e8a46 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,5 +1,5 @@ { "compilerOptions": { - "baseUrl": "." + "baseUrl": "./src" } -} \ No newline at end of file +} diff --git a/lang-ignore.json b/lang-ignore.json index d4707cda..4a0f9d41 100644 --- a/lang-ignore.json +++ b/lang-ignore.json @@ -1,16 +1,32 @@ { "cs-CZ": ["label.reset", "metrics.device.tablet"], - "de-DE": [ - "label.administrator", - "label.name", + "de-CH": [ + "label.admin", + "label.analytics", + "label.desktop", + "label.details", "label.domain", - "label.theme", - "metrics.device.desktop", - "metrics.device.laptop", - "metrics.device.tablet", - "metrics.referrers", - "metrics.utm", - "metrics.utm_medium" + "label.laptop", + "label.tablet", + "label.name", + "label.sessions", + "label.team", + "label.team-id", + "label.teams" + ], + "de-DE": [ + "label.admin", + "label.analytics", + "label.desktop", + "label.details", + "label.domain", + "label.laptop", + "label.tablet", + "label.name", + "label.sessions", + "label.team", + "label.team-id", + "label.teams" ], "en-GB": "*", "fr-FR": ["metrics.actions", "metrics.pages"], @@ -22,12 +38,15 @@ ], "nb-NO": ["label.administrator", "label.dashboard"], "nl-NL": [ - "label.administrator", - "label.websites", - "metrics.browsers", - "metrics.device.desktop", - "metrics.device.laptop", - "metrics.device.tablet" + "label.analytics", + "label.browsers", + "label.laptop", + "label.tablet", + "label.team", + "label.team-id", + "label.teams", + "label.website-id", + "label.websites" ], "it-IT": [ "label.password", @@ -37,9 +56,5 @@ "metrics.device.tablet", "metrics.filter.raw" ], - "pt-PT": [ - "label.websites", - "metrics.device.desktop", - "metrics.device.tablet" - ] + "pt-PT": ["label.websites", "metrics.device.desktop", "metrics.device.tablet"] } diff --git a/lang/am-ET.json b/lang/am-ET.json deleted file mode 100644 index f58a25cd..00000000 --- a/lang/am-ET.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "label.accounts": "Accounts", - "label.add-account": "Add account", - "label.add-column": "Add column", - "label.add-filter": "Add filter", - "label.add-website": "Add website", - "label.administrator": "Administrator", - "label.all": "All", - "label.all-time": "All time", - "label.all-websites": "All websites", - "label.back": "Back", - "label.cancel": "Cancel", - "label.change-password": "Change password", - "label.confirm-password": "Confirm password", - "label.copy-to-clipboard": "Copy to clipboard", - "label.current-password": "Current password", - "label.custom-range": "Custom range", - "label.dashboard": "Dashboard", - "label.date-range": "Date range", - "label.default-date-range": "Default date range", - "label.delete": "Delete", - "label.delete-account": "Delete account", - "label.delete-website": "Delete website", - "label.dismiss": "Dismiss", - "label.domain": "Domain", - "label.edit": "Edit", - "label.edit-account": "Edit account", - "label.edit-website": "Edit website", - "label.enable-share-url": "Enable share URL", - "label.event-data": "Event Data", - "label.field-name": "Field Name", - "label.invalid": "Invalid", - "label.invalid-domain": "Invalid domain", - "label.language": "Language", - "label.last-days": "Last {x} days", - "label.last-hours": "Last {x} hours", - "label.logged-in-as": "Logged in as {username}", - "label.login": "Login", - "label.logout": "Logout", - "label.more": "More", - "label.name": "Name", - "label.new-password": "New password", - "label.none": "None", - "label.owner": "Owner", - "label.password": "Password", - "label.passwords-dont-match": "Passwords don't match", - "label.profile": "Profile", - "label.realtime": "Realtime", - "label.realtime-logs": "Realtime logs", - "label.refresh": "Refresh", - "label.required": "Required", - "label.reset": "Reset", - "label.reset-website": "Reset statistics", - "label.save": "Save", - "label.search": "Search", - "label.settings": "Settings", - "label.share-url": "Share URL", - "label.single-day": "Single day", - "label.theme": "Theme", - "label.this-month": "This month", - "label.this-week": "This week", - "label.this-year": "This year", - "label.timezone": "Timezone", - "label.today": "Today", - "label.tracking-code": "Tracking code", - "label.type": "Type", - "label.unknown": "Unknown", - "label.username": "Username", - "label.value": "Value", - "label.view-details": "View details", - "label.websites": "Websites", - "label.yesterday": "Yesterday", - "message.active-users": "{x} current {x, plural, one {visitor} other {visitors}}", - "message.confirm-delete": "Are you sure you want to delete {target}?", - "message.confirm-reset": "Are you sure you want to reset {target}'s statistics?", - "message.copied": "Copied!", - "message.delete-warning": "All associated data will be deleted as well.", - "message.edit-dashboard": "Edit dashboard", - "message.failure": "Something went wrong.", - "message.get-share-url": "Get share URL", - "message.get-tracking-code": "Get tracking code", - "message.go-to-settings": "Go to settings", - "message.incorrect-username-password": "Incorrect username/password.", - "message.log.visitor": "Visitor from {country} using {browser} on {os} {device}", - "message.new-version-available": "A new version of umami {version} is available!", - "message.no-data-available": "No data available.", - "message.no-websites-configured": "You don't have any websites configured.", - "message.page-not-found": "Page not found.", - "message.powered-by": "Powered by {name}", - "message.reset-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", - "message.save-success": "Saved successfully.", - "message.share-url": "This is the publicly shared URL for {target}.", - "message.toggle-charts": "Toggle charts", - "message.track-stats": "To track stats for {target}, place the following code in the {head} section of your website.", - "message.type-delete": "Type {delete} in the box below to confirm.", - "message.type-reset": "Type {reset} in the box below to confirm.", - "metrics.actions": "Actions", - "metrics.average-visit-time": "Average visit time", - "metrics.bounce-rate": "Bounce rate", - "metrics.browsers": "Browsers", - "metrics.countries": "Countries", - "metrics.device.desktop": "Desktop", - "metrics.device.laptop": "Laptop", - "metrics.device.mobile": "Mobile", - "metrics.device.tablet": "Tablet", - "metrics.devices": "Devices", - "metrics.events": "Events", - "metrics.filter.combined": "Combined", - "metrics.filter.raw": "Raw", - "metrics.languages": "Languages", - "metrics.operating-systems": "Operating systems", - "metrics.page-views": "Page views", - "metrics.pages": "Pages", - "metrics.query-parameters": "Query parameters", - "metrics.referrers": "Referrers", - "metrics.screens": "Screens", - "metrics.unique-visitors": "Unique visitors", - "metrics.views": "Views", - "metrics.visitors": "Visitors" -} diff --git a/lang/de-CH.json b/lang/de-CH.json deleted file mode 100644 index 03980e5c..00000000 --- a/lang/de-CH.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "label.access-code": "Access code", - "label.actions": "Aktione", - "label.activity-log": "Activity log", - "label.add-website": "Websiite hinzuefüege", - "label.admin": "Administrator", - "label.all": "Alli", - "label.all-time": "Gesamte Zitruum", - "label.analytics": "Analytics", - "label.average-visit-time": "Durchschn. Bsuechsziit", - "label.back": "Zrugg", - "label.bounce-rate": "Absprungsrate", - "label.browsers": "Browser", - "label.cancel": "Abbreche", - "label.change-password": "Passwort ändere", - "label.cities": "Cities", - "label.clear-all": "Clear all", - "label.confirm": "Confirm", - "label.confirm-password": "Passwort widerhole", - "label.continue": "Continue", - "label.countries": "Länder", - "label.create-team": "Create team", - "label.create-user": "Create user", - "label.created": "Created", - "label.current-password": "Jetzigs Passwort", - "label.custom-range": "Benutzerdefinierte Bereich", - "label.dashboard": "Übersicht", - "label.data": "Data", - "label.date-range": "Datumsbereich", - "label.default-date-range": "Vorigstellte Datumsbereich", - "label.delete": "Lösche", - "label.delete-team": "Delete team", - "label.delete-user": "Delete user", - "label.delete-website": "Websiite lösche", - "label.desktop": "Desktop", - "label.details": "Details", - "label.devices": "Grät", - "label.dismiss": "Verwerfe", - "label.domain": "Domain", - "label.edit": "Bearbeite", - "label.edit-dashboard": "Dashboard bearbeite", - "label.enable-share-url": "Freigab-URL aktiviere", - "label.events": "Ereigniss", - "label.filter-combined": "Kombiniert", - "label.filter-raw": "Rohdate", - "label.join": "Join", - "label.join-team": "Join team", - "label.language": "Sprach", - "label.languages": "Sprache", - "label.laptop": "Laptop", - "label.last-days": "Letzti {x} Täg", - "label.last-hours": "Letzti {x} Stunde", - "label.leave": "Leave", - "label.leave-team": "Leave team", - "label.login": "Login", - "label.logout": "Abmelde", - "label.members": "Members", - "label.mobile": "Handy", - "label.more": "Meh", - "label.name": "Name", - "label.new-password": "Neus Passwort", - "label.none": "Keis", - "label.operating-systems": "Betriebssystem", - "label.owner": "Bsitzer", - "label.page-views": "Siitenufrüef", - "label.pages": "Siite", - "label.password": "Passwort", - "label.powered-by": "Betribe dur {name}", - "label.profile": "Profil", - "label.queries": "Queries", - "label.query-parameters": "Abfragparameter", - "label.realtime": "Echtzit", - "label.referrers": "Referrer", - "label.refresh": "Aktualisiere", - "label.regenerate": "Regenerate", - "label.regions": "Regions", - "label.remove": "Remove", - "label.required": "Erforderlich", - "label.reset": "Zruggsetze", - "label.reset-website": "Statistik zruggsetze", - "label.role": "Role", - "label.save": "Speichere", - "label.screens": "Bildschirmuflösige", - "label.select-website": "Select website", - "label.sessions": "Sessions", - "label.settings": "Istellige", - "label.share-url": "Freigab-URL", - "label.single-day": "Ein Tag", - "label.tablet": "Tablet", - "label.team": "Team", - "label.team-guest": "Team guest", - "label.team-id": "Team ID", - "label.team-member": "Team member", - "label.team-owner": "Team owner", - "label.teams": "Teams", - "label.theme": "Thema", - "label.this-month": "De Monet", - "label.this-week": "Die Wuche", - "label.this-year": "Das Jahr", - "label.timezone": "Zitzone", - "label.title": "Title", - "label.today": "Hüt", - "label.toggle-charts": "Schaubilder umschalte", - "label.tracking-code": "Tracking Code", - "label.unique-visitors": "Eidütigi Bsuecher", - "label.unknown": "Unbekannt", - "label.user": "User", - "label.username": "Benutzername", - "label.users": "Users", - "label.view": "View", - "label.view-details": "Details azeige", - "label.views": "Ufrüef", - "label.visitors": "Bsuecher", - "label.website-id": "Website ID", - "label.websites": "Websiite", - "label.yesterday": "Gester", - "message.active-users": "{x} {x, plural, one {aktive Bsuecher} other {aktivi Bsuecher}}", - "message.confirm-delete": "Sind Sie sich sicher, {target} zlösche?", - "message.confirm-leave": "Are you sure you want to leave {target}?", - "message.confirm-reset": "Sind Sie sicher, dass Sie dStatistike vo {target} zruggsetze wend?", - "message.delete-website": "Websiite lösche", - "message.delete-website-warning": "Alli dezueghörige Date werdet ebefalls glöscht.", - "message.error": "Es isch en Fehler uftrete.", - "message.event-log": "{event} on {url}", - "message.go-to-settings": "Zu de Istellige", - "message.incorrect-username-password": "Falschs Passwort oder Benutzername.", - "message.invalid-domain": "Ungültigi Domain", - "message.min-password-length": "Minimum length of {n} characters", - "message.no-data-available": "Kei Date vorhande.", - "message.no-match-password": "Passwörter stimmed ned überi", - "message.no-teams": "You have not created any teams.", - "message.no-users": "There are no users.", - "message.page-not-found": "Siite ned gfunde.", - "message.reset-website": "Statistik zruggsetze", - "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": "Das isch die öffentlichi URL zum Teile für {target}.", - "message.team-already-member": "You are already a member of the team.", - "message.team-not-found": "Team not found.", - "message.tracking-code": "Tracking Code", - "message.user-deleted": "User deleted.", - "message.visitor-log": "Bsuecher us {country} benutzt {browser} uf {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Es isch kei Websiite vorhande.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." -} diff --git a/lang/hr-HR.json b/lang/hr-HR.json deleted file mode 100644 index e9072a89..00000000 --- a/lang/hr-HR.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "label.accounts": "Računi", - "label.add-account": "Dodaj račun", - "label.add-column": "Dodaj stupac", - "label.add-filter": "Dodaj filter", - "label.add-website": "Dodaj web stranicu", - "label.administrator": "Administrator", - "label.all": "Sve", - "label.all-time": "Svo vrijeme", - "label.all-websites": "Sve web stranice", - "label.back": "Natrag ", - "label.cancel": "Odustani", - "label.change-password": "Promijeni lozinku", - "label.confirm-password": "Potvrdi lozinku", - "label.copy-to-clipboard": "Kopiraj u međuspremnik", - "label.current-password": "Trenutna lozinka", - "label.custom-range": "Prilagođeni raspon", - "label.dashboard": "Nadzorna ploča", - "label.date-range": "Raspon datuma", - "label.default-date-range": "Zadani datumski raspon", - "label.delete": "Obriši", - "label.delete-account": "Obriši račun", - "label.delete-website": "Obriši web stranicu", - "label.dismiss": "Odbaci", - "label.domain": "Domena", - "label.edit": "Uredi", - "label.edit-account": "Uredi račun", - "label.edit-website": "Uredi web stranicu", - "label.enable-share-url": "Omogući dijeljenje poveznice", - "label.event-data": "Podaci događaja", - "label.field-name": "Naziv polja", - "label.invalid": "Neispravno", - "label.invalid-domain": "Neispravna domena", - "label.language": "Jezik", - "label.last-days": "Zadnjih {x} dana", - "label.last-hours": "Zadnjih {x} sati", - "label.logged-in-as": "Prijavljen kao {username}", - "label.login": "Prijava", - "label.logout": "Odjava", - "label.more": "Više", - "label.name": "Ime", - "label.new-password": "Nova lozinka", - "label.none": "Ništa", - "label.owner": "Vlasnik", - "label.password": "Lozinka", - "label.passwords-dont-match": "Lozinke se ne podudaraju", - "label.profile": "Profil", - "label.realtime": "Stvarno vrijeme", - "label.realtime-logs": "Trenutni zapisi", - "label.refresh": "Osvježi", - "label.required": "Potrebna", - "label.reset": "Resetirati", - "label.reset-website": "Resetirati web stranicu", - "label.save": "Spremi", - "label.search": "Pretraži", - "label.settings": "Postavke", - "label.share-url": "Podijeli poveznicu", - "label.single-day": "Jedan dan", - "label.theme": "Tema", - "label.this-month": "Ovaj mjesec", - "label.this-week": "Ovaj tjedan", - "label.this-year": "Ova godina", - "label.timezone": "Vremenska zona", - "label.today": "Danas", - "label.tracking-code": "Kod za praćenje", - "label.type": "Tip", - "label.unknown": "Nepoznato", - "label.username": "Korisničko ime", - "label.value": "Vrijednost", - "label.view-details": "Pogledaj detalje", - "label.websites": "Web stranice", - "label.yesterday": "Jučer", - "message.active-users": "{x} Trenutno {x, plural, one {posjetitelj} other {posjetitelja}}", - "message.confirm-delete": "Jeste li sigurni da želite obrisati {target}?", - "message.confirm-reset": "Jeste li sigurni da želite resetirati {target}'s statistiku?", - "message.copied": "Kopirano!", - "message.delete-warning": "Izbrisat će se svi povezani podaci.", - "message.edit-dashboard": "Uredi nadzornu ploču", - "message.failure": "Nešto je pošlo po zlu.", - "message.get-share-url": "Dohvati poveznicu za dijeljenje", - "message.get-tracking-code": "Dohvati kod za praćenje", - "message.go-to-settings": "Idi u postavke", - "message.incorrect-username-password": "Neispravno korisničke ime/lozinka.", - "message.log.visitor": "Posjetitelj iz {country} koristi {browser} na {os} {device}", - "message.new-version-available": "Nova verzija umami {version} je dostupna!", - "message.no-data-available": "Nema dostupnih podataka.", - "message.no-websites-configured": "Nemate konfiguriranu nijednu web stranicu.", - "message.page-not-found": "Stranica nije pronađena.", - "message.powered-by": "Pokreće {name}", - "message.reset-warning": "Sve statistike za ovu web stranicu bit će izbrisane, ali će vaš kod za praćenje ostati netaknut.", - "message.save-success": "Uspješno spremljeno.", - "message.share-url": "Ovo je javno dijeljena poveznica za {target}.", - "message.toggle-charts": "Uključi/isključi grafikone", - "message.track-stats": "Da biste pratili statistiku za {target}, postavite sljedeći kod u odjeljak {head} svoje web stranice.", - "message.type-delete": "Upišite {delete} u donji okvir za potvrdu.", - "message.type-reset": " Upišite {reset} u donji okvir za potvrdu. ", - "metrics.actions": "Akcije", - "metrics.average-visit-time": "Prosječno vrijeme posjeta", - "metrics.bounce-rate": "Stopa napuštanja stranice", - "metrics.browsers": "Web preglednici", - "metrics.countries": "Zemlje", - "metrics.device.desktop": "Pc", - "metrics.device.laptop": "Laptop", - "metrics.device.mobile": "Mobitel", - "metrics.device.tablet": "Tablet", - "metrics.devices": "Uređaji", - "metrics.events": "Događaji", - "metrics.filter.combined": "Kombinirano", - "metrics.filter.raw": "Neobrađeni podaci", - "metrics.languages": "Jezici", - "metrics.operating-systems": "Operativni sustavi", - "metrics.page-views": "Pregledi stranice", - "metrics.pages": "Stranice", - "metrics.query-parameters": "Parametri upita", - "metrics.referrers": "Upučivaći", - "metrics.screens": "Zasloni", - "metrics.unique-visitors": "Jedinstveni posjetitelji", - "metrics.views": "Pregledi", - "metrics.visitors": "Posjetitelji" -} diff --git a/lang/ja-JP.json b/lang/ja-JP.json deleted file mode 100644 index 58a326bd..00000000 --- a/lang/ja-JP.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "label.access-code": "Access code", - "label.actions": "アクション", - "label.activity-log": "Activity log", - "label.add-website": "Webサイトの追加", - "label.admin": "管理者", - "label.all": "すべて表示", - "label.all-time": "All time", - "label.analytics": "Analytics", - "label.average-visit-time": "平均滞在時間", - "label.back": "戻る", - "label.bounce-rate": "直帰率", - "label.browsers": "ブラウザ", - "label.cancel": "キャンセル", - "label.change-password": "パスワード変更", - "label.cities": "Cities", - "label.clear-all": "Clear all", - "label.confirm": "Confirm", - "label.confirm-password": "パスワード(確認)", - "label.continue": "Continue", - "label.countries": "国", - "label.create-team": "Create team", - "label.create-user": "Create user", - "label.created": "Created", - "label.current-password": "現在のパスワード", - "label.custom-range": "期間を指定する", - "label.dashboard": "ダッシュボード", - "label.data": "Data", - "label.date-range": "範囲指定", - "label.default-date-range": "最初に表示する期間", - "label.delete": "削除", - "label.delete-team": "Delete team", - "label.delete-user": "Delete user", - "label.delete-website": "Webサイトの削除", - "label.desktop": "デスクトップ", - "label.details": "Details", - "label.devices": "デバイス", - "label.dismiss": "無視する", - "label.domain": "ドメイン", - "label.edit": "編集", - "label.edit-dashboard": "Edit dashboard", - "label.enable-share-url": "共有リンクを有効にする", - "label.events": "イベント", - "label.filter-combined": "パスまで", - "label.filter-raw": "すべて表示", - "label.join": "Join", - "label.join-team": "Join team", - "label.language": "Language", - "label.languages": "Languages", - "label.laptop": "ノートPC", - "label.last-days": "過去{x}日間", - "label.last-hours": "過去{x}時間", - "label.leave": "Leave", - "label.leave-team": "Leave team", - "label.login": "ログイン", - "label.logout": "ログアウト", - "label.members": "Members", - "label.mobile": "携帯電話", - "label.more": "さらに表示", - "label.name": "名前", - "label.new-password": "新しいパスワード", - "label.none": "None", - "label.operating-systems": "OS", - "label.owner": "Owner", - "label.page-views": "閲覧数", - "label.pages": "ページ", - "label.password": "パスワード", - "label.powered-by": "このシステムは {name} で実行されています。", - "label.profile": "プロファイル", - "label.queries": "Queries", - "label.query-parameters": "Query parameters", - "label.realtime": "リアルタイム", - "label.referrers": "リファラー", - "label.refresh": "更新", - "label.regenerate": "Regenerate", - "label.regions": "Regions", - "label.remove": "Remove", - "label.required": "必須", - "label.reset": "リセット", - "label.reset-website": "Reset statistics", - "label.role": "Role", - "label.save": "保存", - "label.screens": "Screens", - "label.select-website": "Select website", - "label.sessions": "Sessions", - "label.settings": "設定", - "label.share-url": "共有リンク", - "label.single-day": "一日のみ", - "label.tablet": "タブレット", - "label.team": "Team", - "label.team-guest": "Team guest", - "label.team-id": "Team ID", - "label.team-member": "Team member", - "label.team-owner": "Team owner", - "label.teams": "Teams", - "label.theme": "Theme", - "label.this-month": "今月", - "label.this-week": "今週", - "label.this-year": "今年", - "label.timezone": "タイムゾーン", - "label.title": "Title", - "label.today": "今日", - "label.toggle-charts": "Toggle charts", - "label.tracking-code": "トラッキングコード", - "label.unique-visitors": "ユニーク訪問者数", - "label.unknown": "不明", - "label.user": "User", - "label.username": "ユーザー名", - "label.users": "Users", - "label.view": "View", - "label.view-details": "詳細を見る", - "label.views": "閲覧数", - "label.visitors": "訪問者数", - "label.website-id": "Website ID", - "label.websites": "Webサイト", - "label.yesterday": "Yesterday", - "message.active-users": "{x}人が閲覧中です。", - "message.confirm-delete": "{target}を削除してもよろしいですか?", - "message.confirm-leave": "Are you sure you want to leave {target}?", - "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Webサイトの削除", - "message.delete-website-warning": "関連するすべてのデータも削除されます。", - "message.error": "問題が発生しました。", - "message.event-log": "{event} on {url}", - "message.go-to-settings": "設定する", - "message.incorrect-username-password": "ユーザー名/パスワードが正しくありません。", - "message.invalid-domain": "無効なドメイン", - "message.min-password-length": "Minimum length of {n} characters", - "message.no-data-available": "データがありません。", - "message.no-match-password": "パスワードが一致しません", - "message.no-teams": "You have not created any teams.", - "message.no-users": "There are no users.", - "message.page-not-found": "ページが見つかりません。", - "message.reset-website": "Reset statistics", - "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", - "message.saved": "正常に保存されました。", - "message.share-url": "これは{target}の共有リンクです。", - "message.team-already-member": "You are already a member of the team.", - "message.team-not-found": "Team not found.", - "message.tracking-code": "トラッキングコード", - "message.user-deleted": "User deleted.", - "message.visitor-log": "{os}({device})で{browser}を使用している{country}からの訪問者", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Webサイトが設定されていません。", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." -} diff --git a/lang/mn-MN.json b/lang/mn-MN.json deleted file mode 100644 index 9e3b4499..00000000 --- a/lang/mn-MN.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "label.access-code": "Access code", - "label.actions": "Үйлдлүүд", - "label.activity-log": "Activity log", - "label.add-website": "Веб нэмэх", - "label.admin": "Админ", - "label.all": "Бүх", - "label.all-time": "Бүх цаг үеийн", - "label.analytics": "Analytics", - "label.average-visit-time": "Зочилсон дундаж хугацаа", - "label.back": "Буцах", - "label.bounce-rate": "Нэг хуудас үзээд гарсан", - "label.browsers": "Хөтөч", - "label.cancel": "Цуцлах", - "label.change-password": "Нууц үг солих", - "label.cities": "Cities", - "label.clear-all": "Clear all", - "label.confirm": "Confirm", - "label.confirm-password": "Шинэ нууц үгээ давтах", - "label.continue": "Continue", - "label.countries": "Улс", - "label.create-team": "Create team", - "label.create-user": "Create user", - "label.created": "Created", - "label.current-password": "Ашиглаж буй нууц үг", - "label.custom-range": "Дурын хугацаа", - "label.dashboard": "Хянах самбар", - "label.data": "Data", - "label.date-range": "Хугацааны мужид", - "label.default-date-range": "Өгөгдмөл хугацааны муж", - "label.delete": "Устгах", - "label.delete-team": "Delete team", - "label.delete-user": "Delete user", - "label.delete-website": "Веб устгах", - "label.desktop": "Суурин компьютер", - "label.details": "Details", - "label.devices": "Төхөөрөмж", - "label.dismiss": "Үл хэргэсэх", - "label.domain": "Домэйн", - "label.edit": "Засах", - "label.edit-dashboard": "Хянах самбар засах", - "label.enable-share-url": "Хуваалцах холбоос идэвхжүүлэх", - "label.events": "Үйлдэл", - "label.filter-combined": "Нэгтгэсэн", - "label.filter-raw": "Түүхий", - "label.join": "Join", - "label.join-team": "Join team", - "label.language": "Хэл", - "label.languages": "Хэл", - "label.laptop": "Зөөврийн компьютер", - "label.last-days": "Сүүлийн {x} хоног", - "label.last-hours": "Сүүлийн {x} цаг", - "label.leave": "Leave", - "label.leave-team": "Leave team", - "label.login": "Нэвтрэх", - "label.logout": "Гарах", - "label.members": "Members", - "label.mobile": "Утас", - "label.more": "Цааш", - "label.name": "Нэр", - "label.new-password": "Шинэ нууц үг", - "label.none": "Байхгүй", - "label.operating-systems": "Үйлдлийн систем", - "label.owner": "Эзэмшигч", - "label.page-views": "Хуудас үзсэн", - "label.pages": "Хуудас", - "label.password": "Нууц үг", - "label.powered-by": "{name} дээр суурилсан", - "label.profile": "Бүртгэл", - "label.queries": "Queries", - "label.query-parameters": "Query параметр", - "label.realtime": "Яг одоо", - "label.referrers": "Чиглүүлэгч", - "label.refresh": "Сэргээх", - "label.regenerate": "Regenerate", - "label.regions": "Regions", - "label.remove": "Remove", - "label.required": "Шаардлагатай", - "label.reset": "Хуучин хэвд нь оруулах", - "label.reset-website": "Тоон үзүүлэлтийг дахин эхлүүлэх", - "label.role": "Role", - "label.save": "Хадгалах", - "label.screens": "Дэлгэц", - "label.select-website": "Select website", - "label.sessions": "Sessions", - "label.settings": "Тохиргоо", - "label.share-url": "Хуваалцах холбоос", - "label.single-day": "Нэг өдөр", - "label.tablet": "Таблет", - "label.team": "Team", - "label.team-guest": "Team guest", - "label.team-id": "Team ID", - "label.team-member": "Team member", - "label.team-owner": "Team owner", - "label.teams": "Teams", - "label.theme": "Загвар", - "label.this-month": "Энэ сар", - "label.this-week": "Энэ долоо хоног", - "label.this-year": "Энэ жил", - "label.timezone": "Цагийн бүс", - "label.title": "Title", - "label.today": "Өнөөдөр", - "label.toggle-charts": "Графикийг харуулах/нуух", - "label.tracking-code": "Мөрдөх код", - "label.unique-visitors": "Зочин", - "label.unknown": "Тодорхойгүй", - "label.user": "User", - "label.username": "Хэрэглэгчийн нэр", - "label.users": "Users", - "label.view": "View", - "label.view-details": "Дэлгэрүүлж харах", - "label.views": "Үзсэн", - "label.visitors": "Зочин", - "label.website-id": "Website ID", - "label.websites": "Вебүүд", - "label.yesterday": "Өчигдөр", - "message.active-users": "одоо {x} {x, plural, one {зочин} other {зочин}} байна", - "message.confirm-delete": "Та {target}-г устгахдаа итгэлтэй байна уу?", - "message.confirm-leave": "Are you sure you want to leave {target}?", - "message.confirm-reset": "Та {target}-н тоон үзүүлэлтүүдийг устгахдаа итгэлтэй байна уу?", - "message.delete-website": "Веб устгах", - "message.delete-website-warning": "Үүнтэй холбоотой бүх өгөгдөл устах болно.", - "message.error": "Ямар нэг зүйл буруу боллоо.", - "message.event-log": "{event} on {url}", - "message.go-to-settings": "Тохиргоо руу очих", - "message.incorrect-username-password": "Буруу хэрэглэгчийн нэр/нууц үг.", - "message.invalid-domain": "Буруу домэйн", - "message.min-password-length": "Minimum length of {n} characters", - "message.no-data-available": "Өгөгдөл алга.", - "message.no-match-password": "Нууц үг тохирохгүй байна", - "message.no-teams": "You have not created any teams.", - "message.no-users": "There are no users.", - "message.page-not-found": "Хуудас олдсонгүй.", - "message.reset-website": "Тоон үзүүлэлтийг дахин эхлүүлэх", - "message.reset-website-warning": "Энэ вебийн бүх тоон үзүүлэлтүүдийг устгах болно. Гэхдээ мөрдөх код хэвэндээ үлдэнэ.", - "message.saved": "Амжилттай хадгаллаа.", - "message.share-url": "{target}-г нийтэд хуваалцах холбоос.", - "message.team-already-member": "You are already a member of the team.", - "message.team-not-found": "Team not found.", - "message.tracking-code": "Мөрдөх код", - "message.user-deleted": "User deleted.", - "message.visitor-log": "{country} улсаас {os} {device} дээр {browser} хөтөч ашиглан орсон", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Та ямар нэгэн веб тохируулаагүй байна.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." -} diff --git a/lang/nl-NL.json b/lang/nl-NL.json deleted file mode 100644 index bac675f9..00000000 --- a/lang/nl-NL.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "label.access-code": "Access code", - "label.actions": "Acties", - "label.activity-log": "Activity log", - "label.add-website": "Website toevoegen", - "label.admin": "Administrator", - "label.all": "Alles", - "label.all-time": "Onbeperkt", - "label.analytics": "Analytics", - "label.average-visit-time": "Gemiddelde bezoektijd", - "label.back": "Terug", - "label.bounce-rate": "Bouncepercentage", - "label.browsers": "Browsers", - "label.cancel": "Annuleren", - "label.change-password": "Wachtwoord wijzigen", - "label.cities": "Cities", - "label.clear-all": "Clear all", - "label.confirm": "Confirm", - "label.confirm-password": "Wachtwoord bevestigen", - "label.continue": "Continue", - "label.countries": "Landen", - "label.create-team": "Create team", - "label.create-user": "Create user", - "label.created": "Created", - "label.current-password": "Huidig wachtwoord", - "label.custom-range": "Aangepast bereik", - "label.dashboard": "Overzicht", - "label.data": "Data", - "label.date-range": "Datumbereik", - "label.default-date-range": "Standaard bereik", - "label.delete": "Verwijderen", - "label.delete-team": "Delete team", - "label.delete-user": "Delete user", - "label.delete-website": "Website verwijderen", - "label.desktop": "Desktop", - "label.details": "Details", - "label.devices": "Apparaten", - "label.dismiss": "Negeren", - "label.domain": "Domein", - "label.edit": "Bewerken", - "label.edit-dashboard": "Edit dashboard", - "label.enable-share-url": "Sta delen via openbare URL toe", - "label.events": "Gebeurtenissen", - "label.filter-combined": "Gecombineerd", - "label.filter-raw": "Ruw", - "label.join": "Join", - "label.join-team": "Join team", - "label.language": "Taal", - "label.languages": "Languages", - "label.laptop": "Laptop", - "label.last-days": "Laatste {x} dagen", - "label.last-hours": "Laatste {x} uur", - "label.leave": "Leave", - "label.leave-team": "Leave team", - "label.login": "Inloggen", - "label.logout": "Uitloggen", - "label.members": "Members", - "label.mobile": "Mobiel", - "label.more": "Toon meer", - "label.name": "Naam", - "label.new-password": "Nieuw wachtwoord", - "label.none": "Geen", - "label.operating-systems": "Besturingssystemen", - "label.owner": "Eigenaar", - "label.page-views": "Paginaweergaven", - "label.pages": "Pagina's", - "label.password": "Wachtwoord", - "label.powered-by": "mogelijk gemaakt door {name}", - "label.profile": "Profiel", - "label.queries": "Queries", - "label.query-parameters": "Query parameters", - "label.realtime": "Actueel", - "label.referrers": "Verwijzers", - "label.refresh": "Vernieuwen", - "label.regenerate": "Regenerate", - "label.regions": "Regions", - "label.remove": "Remove", - "label.required": "Verplicht", - "label.reset": "Resetten", - "label.reset-website": "Statistieken opnieuw instellen", - "label.role": "Role", - "label.save": "Opslaan", - "label.screens": "Schermen", - "label.select-website": "Select website", - "label.sessions": "Sessions", - "label.settings": "Instellingen", - "label.share-url": "URL delen", - "label.single-day": "Enkele dag", - "label.tablet": "Tablet", - "label.team": "Team", - "label.team-guest": "Team guest", - "label.team-id": "Team ID", - "label.team-member": "Team member", - "label.team-owner": "Team owner", - "label.teams": "Teams", - "label.theme": "Thema", - "label.this-month": "Deze maand", - "label.this-week": "Deze week", - "label.this-year": "Dit jaar", - "label.timezone": "Tijdzone", - "label.title": "Title", - "label.today": "Vandaag", - "label.toggle-charts": "Grafieken tonen/verbergen", - "label.tracking-code": "Volgcode", - "label.unique-visitors": "Unieke bezoekers", - "label.unknown": "Onbekend", - "label.user": "User", - "label.username": "Gebruikersnaam", - "label.users": "Users", - "label.view": "View", - "label.view-details": "Meer details", - "label.views": "Weergaven", - "label.visitors": "Bezoekers", - "label.website-id": "Website ID", - "label.websites": "Websites", - "label.yesterday": "Yesterday", - "message.active-users": "{x} actieve {x, plural, one {bezoeker} other {bezoekers}}", - "message.confirm-delete": "Weet je zeker dat je {target} wilt verwijderen?", - "message.confirm-leave": "Are you sure you want to leave {target}?", - "message.confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?", - "message.delete-website": "Website verwijderen", - "message.delete-website-warning": "Alle verwante gegezens zullen ook verwijderd worden.", - "message.error": "Er is iets misgegaan.", - "message.event-log": "{event} on {url}", - "message.go-to-settings": "Naar instellingen", - "message.incorrect-username-password": "Incorrecte gebruikersnaam/wachtwoord.", - "message.invalid-domain": "Ongeldig domein", - "message.min-password-length": "Minimum length of {n} characters", - "message.no-data-available": "Geen gegevens beschikbaar.", - "message.no-match-password": "Wachtwoorden komen niet overeen", - "message.no-teams": "You have not created any teams.", - "message.no-users": "There are no users.", - "message.page-not-found": "Pagina niet gevonden.", - "message.reset-website": "Statistieken opnieuw instellen", - "message.reset-website-warning": "Alle bijhorende statistieken van deze website worden verwijderd, maar jouw volgcode blijft gelden.", - "message.saved": "Opslaan succesvol.", - "message.share-url": "Met deze URL kan {target} openbaar gedeeld worden.", - "message.team-already-member": "You are already a member of the team.", - "message.team-not-found": "Team not found.", - "message.tracking-code": "Volgcode", - "message.user-deleted": "User deleted.", - "message.visitor-log": "Bezoeker uit {country} met {browser} op een {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Je hebt geen websites ingesteld.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." -} diff --git a/lang/pt-BR.json b/lang/pt-BR.json deleted file mode 100644 index f02b7fb9..00000000 --- a/lang/pt-BR.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "label.access-code": "Access code", - "label.actions": "Ações", - "label.activity-log": "Activity log", - "label.add-website": "Adicionar site", - "label.admin": "Administrador", - "label.all": "Todos", - "label.all-time": "Todo o período", - "label.analytics": "Analytics", - "label.average-visit-time": "Tempo médio da visita", - "label.back": "Voltar", - "label.bounce-rate": "Taxa de rejeição", - "label.browsers": "Navegadores", - "label.cancel": "Cancelar", - "label.change-password": "Alterar a senha", - "label.cities": "Cities", - "label.clear-all": "Clear all", - "label.confirm": "Confirm", - "label.confirm-password": "Confirme a nova senha", - "label.continue": "Continue", - "label.countries": "Países", - "label.create-team": "Create team", - "label.create-user": "Create user", - "label.created": "Created", - "label.current-password": "Senha atual", - "label.custom-range": "Intervalo personalizado", - "label.dashboard": "Painel", - "label.data": "Data", - "label.date-range": "Intervalo de datas", - "label.default-date-range": "Intervalo de datas predefinido", - "label.delete": "Remover", - "label.delete-team": "Delete team", - "label.delete-user": "Delete user", - "label.delete-website": "Remover site", - "label.desktop": "Computador", - "label.details": "Details", - "label.devices": "Dispositivos", - "label.dismiss": "Dispensar", - "label.domain": "Domínio", - "label.edit": "Editar", - "label.edit-dashboard": "Edit dashboard", - "label.enable-share-url": "Ativar link de compartilhamento", - "label.events": "Eventos", - "label.filter-combined": "Combinado", - "label.filter-raw": "Dados brutos", - "label.join": "Join", - "label.join-team": "Join team", - "label.language": "Idioma", - "label.languages": "Idiomas", - "label.laptop": "Notebook", - "label.last-days": "Últimos {x} dias", - "label.last-hours": "Últimas {x} horas", - "label.leave": "Leave", - "label.leave-team": "Leave team", - "label.login": "Iniciar sessão", - "label.logout": "Sair", - "label.members": "Members", - "label.mobile": "Celular", - "label.more": "Mais", - "label.name": "Nome", - "label.new-password": "Nova senha", - "label.none": "None", - "label.operating-systems": "Sistemas operacionais", - "label.owner": "Proprietário", - "label.page-views": "Visualizações de página", - "label.pages": "Páginas", - "label.password": "Senha", - "label.powered-by": "Distribuído por {name}", - "label.profile": "Perfil", - "label.queries": "Queries", - "label.query-parameters": "Parâmetros de Consulta", - "label.realtime": "Tempo real", - "label.referrers": "Referências", - "label.refresh": "Atualizar", - "label.regenerate": "Regenerate", - "label.regions": "Regions", - "label.remove": "Remove", - "label.required": "Obrigatório", - "label.reset": "Redefinir", - "label.reset-website": "Redefinir estatísticas", - "label.role": "Role", - "label.save": "Salvar", - "label.screens": "Telas", - "label.select-website": "Select website", - "label.sessions": "Sessions", - "label.settings": "Configurações", - "label.share-url": "Link de compartilhamento", - "label.single-day": "Dia específico", - "label.tablet": "Tablet", - "label.team": "Team", - "label.team-guest": "Team guest", - "label.team-id": "Team ID", - "label.team-member": "Team member", - "label.team-owner": "Team owner", - "label.teams": "Teams", - "label.theme": "Tema", - "label.this-month": "Este mês", - "label.this-week": "Esta semana", - "label.this-year": "Este ano", - "label.timezone": "Fuso horário", - "label.title": "Title", - "label.today": "Hoje", - "label.toggle-charts": "Mostrar/Esconder gráficos", - "label.tracking-code": "Código de rastreamento", - "label.unique-visitors": "Visitantes únicos", - "label.unknown": "Desconhecido", - "label.user": "User", - "label.username": "Nome de usuário", - "label.users": "Users", - "label.view": "View", - "label.view-details": "Ver detalhes", - "label.views": "Visualizações", - "label.visitors": "Visitantes", - "label.website-id": "Website ID", - "label.websites": "Sites", - "label.yesterday": "Ontem", - "message.active-users": "{x} {x, plural, one {visitante} other {visitantes}} neste momento", - "message.confirm-delete": "Deseja realmente remover {target}?", - "message.confirm-leave": "Are you sure you want to leave {target}?", - "message.confirm-reset": "Você tem certeza que deseja redefinir as estatísticas de {target}?", - "message.delete-website": "Remover site", - "message.delete-website-warning": "Todos os dados associados também serão eliminados.", - "message.error": "Ocorreu um erro.", - "message.event-log": "{event} on {url}", - "message.go-to-settings": "Ir para as configurações", - "message.incorrect-username-password": "O nome de usuário e/ou senha está incorreto.", - "message.invalid-domain": "Domínio inválido", - "message.min-password-length": "Minimum length of {n} characters", - "message.no-data-available": "Sem dados disponíveis.", - "message.no-match-password": "As senhas não correspondem", - "message.no-teams": "You have not created any teams.", - "message.no-users": "There are no users.", - "message.page-not-found": "Página não encontrada.", - "message.reset-website": "Redefinir estatísticas", - "message.reset-website-warning": "Todas as estatísticas deste site serão removidas, mas seu código de rastreamento permanecerá intacto.", - "message.saved": "Salvo com sucesso.", - "message.share-url": "Este é o link público de compartilhamento para {target}.", - "message.team-already-member": "You are already a member of the team.", - "message.team-not-found": "Team not found.", - "message.tracking-code": "Código de rastreamento", - "message.user-deleted": "User deleted.", - "message.visitor-log": "Visitante de {country} usando {browser} no {device} {os}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Nenhum site foi configurado ainda.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." -} diff --git a/lang/si-LK.json b/lang/si-LK.json deleted file mode 100644 index 33346087..00000000 --- a/lang/si-LK.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "label.accounts": "ගිණුම්", - "label.add-account": "ගිණුම එකතු කරන්න", - "label.add-column": "තීරුව එක් කරන්න", - "label.add-filter": "පෙරහන එකතු කරන්න", - "label.add-website": "වෙබ් අඩවිය එක් කරන්න", - "label.administrator": "පරිපාලක", - "label.all": "සියල්ල", - "label.all-time": "හැම වෙලාවෙම", - "label.all-websites": "සියලුම වෙබ් අඩවි", - "label.back": "ආපසු", - "label.cancel": "අවලංගු කරන්න", - "label.change-password": "මුරපදය වෙනස් කරන්න", - "label.confirm-password": "මුරපදය සත්‍යාපනය කරන්න", - "label.copy-to-clipboard": "පසුරු පුවරුවට පිටපත් කරන්න", - "label.current-password": "වත්මන් මුරපදය", - "label.custom-range": "අභිරුචි පරාසය", - "label.dashboard": "උපකරණ පුවරුව", - "label.date-range": "දින පරාසය", - "label.default-date-range": "පෙරනිමි දින පරාසය", - "label.delete": "මකන්න", - "label.delete-account": "ගිණුම මකන්න", - "label.delete-website": "වෙබ් අඩවිය මකන්න", - "label.dismiss": "මගහරින්න", - "label.domain": "වසම", - "label.edit": "සංස්කරණය කරන්න", - "label.edit-account": "ගිණුම සංස්කරණය කරන්න", - "label.edit-website": "වෙබ් අඩවිය සංස්කරණය කරන්න", - "label.enable-share-url": "බෙදාගැනීමේ URL සබල කරන්න", - "label.event-data": "සිදුවීම් දත්ත", - "label.field-name": "ක්ෂේත්‍ර නාම", - "label.invalid": "වලංගු නැත", - "label.invalid-domain": "වලංගු නොවන වසමක්", - "label.language": "භාෂාව", - "label.last-days": "අන්තිම {x} දින", - "label.last-hours": "අන්තිම {x} පැය", - "label.logged-in-as": "ලොග් වී ඇත්තේ {username}", - "label.login": "ලොග් වෙන්න", - "label.logout": "පිටවීම", - "label.more": "තවත්", - "label.name": "නම", - "label.new-password": "අලුත් මුරපදය", - "label.none": "කිසිවක් නැත", - "label.owner": "හිමිකරු", - "label.password": "මුරපදය", - "label.passwords-dont-match": "මුරපද නොගැලපේ", - "label.profile": "පැතිකඩ", - "label.realtime": "තත්ය කාල", - "label.realtime-logs": "තත්‍ය කාලීන ලොග්", - "label.refresh": "නැවුම් කරන්න", - "label.required": "අවශ්‍යයි", - "label.reset": "යළි පිහිටුවන්න", - "label.reset-website": "සංඛ්යා ලේඛන නැවත සකසන්න", - "label.save": "සුරකින්න", - "label.search": "සෙවීම", - "label.settings": "සැකසුම්", - "label.share-url": "බෙදාගැනීමේ URL", - "label.single-day": "තනි දවස", - "label.theme": "තේමාව", - "label.this-month": "මෙ මාසය", - "label.this-week": "මේ සතිය", - "label.this-year": "මේ අවුරුද්ද", - "label.timezone": "වේලා කලාපය", - "label.today": "අද", - "label.tracking-code": "ලුහුබැඳීමේ කේතය", - "label.type": "වර්ගය", - "label.unknown": "නොදනී", - "label.username": "පරිශීලක නාමය", - "label.value": "වටිනාකම", - "label.view-details": "තොරතුරු පෙන්වන්න", - "label.websites": "වෙබ් අඩවි", - "label.yesterday": "ඊයේ", - "message.active-users": "{x} දැන් {x, plural, one {අමුත්තා} other {අමුත්තන්}}", - "message.confirm-delete": "{target} මකා දැමීම ගැන විශ්වාසද?", - "message.confirm-reset": "{target} ට අදාල සංඛ්‍යාලේඛන නැවත පිහිටුවීමට අවශ්‍යද?", - "message.copied": "පිටපත් කරගත්තා!", - "message.delete-warning": "සියලුම ආශ්‍රිත දත්ත ද මකා දැමෙනු ඇත.", - "message.edit-dashboard": "උපකරණ පුවරුව සංස්කරණය කරන්න", - "message.failure": "යම් ගැටලුවක් මතු වී ඇත.", - "message.get-share-url": "බෙදාගැනීමේ URL ලබා ගන්න", - "message.get-tracking-code": "ලුහුබැඳීමේ කේතය ලබා ගන්න", - "message.go-to-settings": "සැකසීම් වෙත යන්න", - "message.incorrect-username-password": "වැරදි පරිශීලක නාමය/මුරපදය.", - "message.log.visitor": "{country} වලින් පැමිණි අමුත්තකු {device} එකේ, මේ {os} එකේ, මේ {browser} එකෙන් ඉන්නවා", - "message.new-version-available": "umami අලුත්ම {version} වන අනුවාදය නිකුත් උනා!", - "message.no-data-available": "පෙන්වීමට දත්ත නොමැත.", - "message.no-websites-configured": "ඔබට වින්‍යාස කර ඇති වෙබ් අඩවි කිසිවක් නොමැත.", - "message.page-not-found": "පිටුව හමු නොවීය.", - "message.powered-by": "බල ගැන්වුයේ {name}", - "message.reset-warning": "සියලුම සංඛ්‍යාලේඛන මකා දමනු ඇත. නමුත් ඔබගේ නිරීක්ෂණ කේතය නොවෙනස්ව පවතිනු ඇත.", - "message.save-success": "සාර්තකව සුරැකිණි.", - "message.share-url": "මේ {target} සඳහා ප්‍රසිද්ධියේ බෙදාගත් URL එකයි.", - "message.toggle-charts": "ප්‍රස්ථාර ටොගල් කරන්න", - "message.track-stats": "{target} හි සංඛ්යාලේඛන බැලීම සදහා, පහත කේතය {head} කොටසට ඇතුලත් කරන්න.", - "message.type-delete": "සත්‍යාපනය සදහා {delete} ලෙස පහල කොටුවේ ටයිප් කරන්න", - "message.type-reset": "සත්‍යාපනය සදහා {reset} ලෙස පහල කොටුවේ ටයිප් කරන්න", - "metrics.actions": "ක්රියාවන්", - "metrics.average-visit-time": "සාමාන්‍ය සංචාර කාලය", - "metrics.bounce-rate": "හැරී යන ප්‍රමාණය", - "metrics.browsers": "බ්‍රව්සර්", - "metrics.countries": "රටවල්", - "metrics.device.desktop": "ඩෙස්ක්ටොප්", - "metrics.device.laptop": "ලැප්ටොප්", - "metrics.device.mobile": "ජංගම", - "metrics.device.tablet": "ටැබ්ලට්", - "metrics.devices": "උපකරණ", - "metrics.events": "සිද්ධීන්", - "metrics.filter.combined": "ඒකාබද්ධ", - "metrics.filter.raw": "අමු", - "metrics.languages": "භාෂා", - "metrics.operating-systems": "මෙහෙයුම් පද්ධති", - "metrics.page-views": "පිටු බැලීම්", - "metrics.pages": "පිටු", - "metrics.query-parameters": "විමසුම් පරාමිතීන්", - "metrics.referrers": "යොමු කරන්නන්", - "metrics.screens": "තිර", - "metrics.unique-visitors": "අලුත්ම අමුත්තන්", - "metrics.views": "බැලූ ගණන", - "metrics.visitors": "අමුත්තන්" -} diff --git a/lang/sv-SE.json b/lang/sv-SE.json deleted file mode 100644 index 16a8d62a..00000000 --- a/lang/sv-SE.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "label.access-code": "Access code", - "label.actions": "Händelser", - "label.activity-log": "Activity log", - "label.add-website": "Lägg till webbsajt", - "label.admin": "Administratör", - "label.all": "Alla", - "label.all-time": "Sedan början", - "label.analytics": "Analytics", - "label.average-visit-time": "Medelbesökstid", - "label.back": "Tillbaka", - "label.bounce-rate": "Avvisningfrekvens", - "label.browsers": "Webbläsare", - "label.cancel": "Avbryt", - "label.change-password": "Byt lösenord", - "label.cities": "Cities", - "label.clear-all": "Clear all", - "label.confirm": "Confirm", - "label.confirm-password": "Bekräfta lösenord", - "label.continue": "Continue", - "label.countries": "Länder", - "label.create-team": "Create team", - "label.create-user": "Create user", - "label.created": "Created", - "label.current-password": "Nuvarande lösenord", - "label.custom-range": "Anpassat urval", - "label.dashboard": "Översikt", - "label.data": "Data", - "label.date-range": "Datumomfång", - "label.default-date-range": "Standard datum-urval", - "label.delete": "Radera", - "label.delete-team": "Delete team", - "label.delete-user": "Delete user", - "label.delete-website": "Radera webbsajt", - "label.desktop": "Stationär", - "label.details": "Details", - "label.devices": "Enheter", - "label.dismiss": "Avbryt", - "label.domain": "Domän", - "label.edit": "Redigera", - "label.edit-dashboard": "Edit dashboard", - "label.enable-share-url": "Aktivera delnings-URL", - "label.events": "Händelser", - "label.filter-combined": "Kombinerade", - "label.filter-raw": "Rådata", - "label.join": "Join", - "label.join-team": "Join team", - "label.language": "Språk", - "label.languages": "Språk", - "label.laptop": "Bärbar", - "label.last-days": "Senaste {x} dagarna", - "label.last-hours": "Senaste {x} timmarna", - "label.leave": "Leave", - "label.leave-team": "Leave team", - "label.login": "Logga in", - "label.logout": "Logga ut", - "label.members": "Members", - "label.mobile": "Mobil", - "label.more": "Mer", - "label.name": "Namn", - "label.new-password": "Nytt lösenord", - "label.none": "None", - "label.operating-systems": "Operativsystem", - "label.owner": "Ägare", - "label.page-views": "Sidvisningar", - "label.pages": "Sidor", - "label.password": "Lösenord", - "label.powered-by": "Drivs av {name}", - "label.profile": "Profil", - "label.queries": "Queries", - "label.query-parameters": "Query parameters", - "label.realtime": "Realtid", - "label.referrers": "Hänvisare", - "label.refresh": "Uppdatera", - "label.regenerate": "Regenerate", - "label.regions": "Regions", - "label.remove": "Remove", - "label.required": "Krävs", - "label.reset": "Återställ", - "label.reset-website": "Återställ statistik", - "label.role": "Role", - "label.save": "Spara", - "label.screens": "Screens", - "label.select-website": "Select website", - "label.sessions": "Sessions", - "label.settings": "Inställningar", - "label.share-url": "Delnings-URL", - "label.single-day": "En dag", - "label.tablet": "Platta", - "label.team": "Team", - "label.team-guest": "Team guest", - "label.team-id": "Team ID", - "label.team-member": "Team member", - "label.team-owner": "Team owner", - "label.teams": "Teams", - "label.theme": "Tema", - "label.this-month": "Denna månad", - "label.this-week": "Denna vecka", - "label.this-year": "Detta år", - "label.timezone": "Tidszon", - "label.title": "Title", - "label.today": "Idag", - "label.toggle-charts": "Visa/göm grafer", - "label.tracking-code": "Spårningskod", - "label.unique-visitors": "Unika besökare", - "label.unknown": "Okänd", - "label.user": "User", - "label.username": "Användarnamn", - "label.users": "Users", - "label.view": "View", - "label.view-details": "Visa detaljer", - "label.views": "Visningar", - "label.visitors": "Besökare", - "label.website-id": "Website ID", - "label.websites": "Webbsajt", - "label.yesterday": "Yesterday", - "message.active-users": "{x} {x, plural, one {besökare} other {besökare}} just nu", - "message.confirm-delete": "Är du säker på att du vill radera {target}?", - "message.confirm-leave": "Are you sure you want to leave {target}?", - "message.confirm-reset": "Är du säker på att du vill återställa statistiken för {target}?", - "message.delete-website": "Radera webbsajt", - "message.delete-website-warning": "All tillhörande data kommer också raderas.", - "message.error": "Något gick fel.", - "message.event-log": "{event} on {url}", - "message.go-to-settings": "Gå till inställningar", - "message.incorrect-username-password": "Felaktigt användarnamn/lösenord.", - "message.invalid-domain": "Ogiltig domän", - "message.min-password-length": "Minimum length of {n} characters", - "message.no-data-available": "Ingen data tillgänglig.", - "message.no-match-password": "Lösenorden är inte samma", - "message.no-teams": "You have not created any teams.", - "message.no-users": "There are no users.", - "message.page-not-found": "Sidan kan inte hittas.", - "message.reset-website": "Återställ statistik", - "message.reset-website-warning": "All statistik för webbsajten tas bort men spårningskoden förblir oförändrad.", - "message.saved": "Sparades!", - "message.share-url": "Det här är den offentliga delnings-URL:en för {target}.", - "message.team-already-member": "You are already a member of the team.", - "message.team-not-found": "Team not found.", - "message.tracking-code": "Spårningskod", - "message.user-deleted": "User deleted.", - "message.visitor-log": "Besökare från {country} med {browser} på {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Du har inga webbsajter.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." -} diff --git a/lang/zh-TW.json b/lang/zh-TW.json deleted file mode 100644 index 42370059..00000000 --- a/lang/zh-TW.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "label.access-code": "Access code", - "label.actions": "用戶行為", - "label.activity-log": "Activity log", - "label.add-website": "增加網站", - "label.admin": "管理員", - "label.all": "所有", - "label.all-time": "所有時間段", - "label.analytics": "Analytics", - "label.average-visit-time": "平均訪問時間", - "label.back": "返回", - "label.bounce-rate": "跳出率", - "label.browsers": "瀏覽器", - "label.cancel": "取消", - "label.change-password": "更新密碼", - "label.cities": "Cities", - "label.clear-all": "Clear all", - "label.confirm": "Confirm", - "label.confirm-password": "確認密碼", - "label.continue": "Continue", - "label.countries": "國家/地區", - "label.create-team": "Create team", - "label.create-user": "Create user", - "label.created": "Created", - "label.current-password": "目前密碼", - "label.custom-range": "自定義時段", - "label.dashboard": "管理面板", - "label.data": "Data", - "label.date-range": "多日", - "label.default-date-range": "默認日期範圍", - "label.delete": "刪除", - "label.delete-team": "Delete team", - "label.delete-user": "Delete user", - "label.delete-website": "刪除網站", - "label.desktop": "桌機", - "label.details": "Details", - "label.devices": "裝置", - "label.dismiss": "關閉", - "label.domain": "域名", - "label.edit": "編輯", - "label.edit-dashboard": "編輯管理面板", - "label.enable-share-url": "啟用分享連結", - "label.events": "行為類別", - "label.filter-combined": "總和", - "label.filter-raw": "原始", - "label.join": "Join", - "label.join-team": "Join team", - "label.language": "語言", - "label.languages": "語言", - "label.laptop": "筆記本", - "label.last-days": "最近 {x} 天", - "label.last-hours": "最近 {x} 小時", - "label.leave": "Leave", - "label.leave-team": "Leave team", - "label.login": "登入", - "label.logout": "退出", - "label.members": "Members", - "label.mobile": "手機", - "label.more": "更多", - "label.name": "名字", - "label.new-password": "新密碼", - "label.none": "無", - "label.operating-systems": "操作系統", - "label.owner": "擁有者", - "label.page-views": "網頁流量", - "label.pages": "網頁", - "label.password": "密碼", - "label.powered-by": "運行 {name}", - "label.profile": "個人資料", - "label.queries": "Queries", - "label.query-parameters": "查詢參數", - "label.realtime": "實時", - "label.referrers": "指入域名", - "label.refresh": "刷新", - "label.regenerate": "Regenerate", - "label.regions": "Regions", - "label.remove": "Remove", - "label.required": "必填", - "label.reset": "重置", - "label.reset-website": "重置統計數據", - "label.role": "Role", - "label.save": "保存", - "label.screens": "屏幕尺寸", - "label.select-website": "Select website", - "label.sessions": "Sessions", - "label.settings": "設置", - "label.share-url": "分享連結", - "label.single-day": "單日", - "label.tablet": "平板", - "label.team": "Team", - "label.team-guest": "Team guest", - "label.team-id": "Team ID", - "label.team-member": "Team member", - "label.team-owner": "Team owner", - "label.teams": "Teams", - "label.theme": "主題", - "label.this-month": "本月", - "label.this-week": "本週", - "label.this-year": "今年", - "label.timezone": "時區", - "label.title": "Title", - "label.today": "今天", - "label.toggle-charts": "切換圖表", - "label.tracking-code": "追蹤代碼", - "label.unique-visitors": "獨立訪客", - "label.unknown": "未知", - "label.user": "User", - "label.username": "用户名", - "label.users": "Users", - "label.view": "View", - "label.view-details": "查看更多", - "label.views": "頁面流量", - "label.visitors": "獨立訪客", - "label.website-id": "Website ID", - "label.websites": "網站", - "label.yesterday": "Yesterday", - "message.active-users": "當前線上 {x} 人", - "message.confirm-delete": "你確定要刪除 {target} 嗎?", - "message.confirm-leave": "Are you sure you want to leave {target}?", - "message.confirm-reset": "您確定要重置 {target} 的數據嗎?", - "message.delete-website": "刪除網站", - "message.delete-website-warning": "所有相關數據將會被刪除。", - "message.error": "出現錯誤。", - "message.event-log": "{event} on {url}", - "message.go-to-settings": "去設定", - "message.incorrect-username-password": "用户名或密碼不正確。", - "message.invalid-domain": "無效域名", - "message.min-password-length": "Minimum length of {n} characters", - "message.no-data-available": "無可用數據。", - "message.no-match-password": "密碼不一致", - "message.no-teams": "You have not created any teams.", - "message.no-users": "There are no users.", - "message.page-not-found": "網頁未找到。", - "message.reset-website": "重置統計數據", - "message.reset-website-warning": "本網站的所有統計數據將被刪除,但您的跟蹤代碼將保持不變。", - "message.saved": "成功保存。", - "message.share-url": "這是 {target} 的分享連結。", - "message.team-already-member": "You are already a member of the team.", - "message.team-not-found": "Team not found.", - "message.tracking-code": "追蹤代碼", - "message.user-deleted": "User deleted.", - "message.visitor-log": "來自{country}的訪客在搭載 {os} 的{device}上使用 {browser} 進行訪問。", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "目前無任何網站設定。", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." -} diff --git a/lib/prisma.ts b/lib/prisma.ts deleted file mode 100644 index 0a10d981..00000000 --- a/lib/prisma.ts +++ /dev/null @@ -1,162 +0,0 @@ -import prisma from '@umami/prisma-client'; -import moment from 'moment-timezone'; -import { MYSQL, POSTGRESQL, getDatabaseType } from 'lib/db'; -import { getEventDataType } from './eventData'; -import { FILTER_COLUMNS } from './constants'; - -const MYSQL_DATE_FORMATS = { - minute: '%Y-%m-%d %H:%i:00', - hour: '%Y-%m-%d %H:00:00', - day: '%Y-%m-%d', - month: '%Y-%m-01', - year: '%Y-01-01', -}; - -const POSTGRESQL_DATE_FORMATS = { - minute: 'YYYY-MM-DD HH24:MI:00', - hour: 'YYYY-MM-DD HH24:00:00', - day: 'YYYY-MM-DD', - month: 'YYYY-MM-01', - year: 'YYYY-01-01', -}; - -function toUuid(): string { - const db = getDatabaseType(process.env.DATABASE_URL); - - if (db === POSTGRESQL) { - return '::uuid'; - } - - if (db === MYSQL) { - return ''; - } -} - -function getDateQuery(field: string, unit: string, timezone?: string): string { - const db = getDatabaseType(process.env.DATABASE_URL); - - if (db === POSTGRESQL) { - if (timezone) { - return `to_char(date_trunc('${unit}', ${field} at time zone '${timezone}'), '${POSTGRESQL_DATE_FORMATS[unit]}')`; - } - return `to_char(date_trunc('${unit}', ${field}), '${POSTGRESQL_DATE_FORMATS[unit]}')`; - } - - if (db === MYSQL) { - if (timezone) { - const tz = moment.tz(timezone).format('Z'); - - return `date_format(convert_tz(${field},'+00:00','${tz}'), '${MYSQL_DATE_FORMATS[unit]}')`; - } - - return `date_format(${field}, '${MYSQL_DATE_FORMATS[unit]}')`; - } -} - -function getTimestampInterval(field: string): string { - const db = getDatabaseType(process.env.DATABASE_URL); - - if (db === POSTGRESQL) { - return `floor(extract(epoch from max(${field}) - min(${field})))`; - } - - if (db === MYSQL) { - return `floor(unix_timestamp(max(${field})) - unix_timestamp(min(${field})))`; - } -} - -function getEventDataFilterQuery( - filters: { - eventKey?: string; - eventValue?: string | number | boolean | Date; - }[], - params: any[], -) { - const query = filters.reduce((ac, cv) => { - const type = getEventDataType(cv.eventValue); - - let value = cv.eventValue; - - ac.push(`and (event_key = $${params.length + 1}`); - params.push(cv.eventKey); - - switch (type) { - case 'number': - ac.push(`and event_numeric_value = $${params.length + 1})`); - params.push(value); - break; - case 'string': - ac.push(`and event_string_value = $${params.length + 1})`); - params.push(decodeURIComponent(cv.eventValue as string)); - break; - case 'boolean': - ac.push(`and event_string_value = $${params.length + 1})`); - params.push(decodeURIComponent(cv.eventValue as string)); - value = cv ? 'true' : 'false'; - break; - case 'date': - ac.push(`and event_date_value = $${params.length + 1})`); - params.push(cv.eventValue); - break; - } - - return ac; - }, []); - - return query.join('\n'); -} - -function getFilterQuery(filters = {}, params = []): string { - const query = Object.keys(filters).reduce((arr, key) => { - const filter = filters[key]; - - if (filter !== undefined) { - const column = FILTER_COLUMNS[key] || key; - arr.push(`and ${column}=$${params.length + 1}`); - params.push(decodeURIComponent(filter)); - } - - return arr; - }, []); - - return query.join('\n'); -} - -function parseFilters( - filters: { [key: string]: any } = {}, - params = [], - sessionKey = 'session_id', -) { - const { os, browser, device, country, region, city } = filters; - - return { - joinSession: - os || browser || device || country || region || city - ? `inner join session on website_event.${sessionKey} = session.${sessionKey}` - : '', - filterQuery: getFilterQuery(filters, params), - }; -} - -async function rawQuery(query: string, params: never[] = []): Promise { - const db = getDatabaseType(process.env.DATABASE_URL); - - if (db !== POSTGRESQL && db !== MYSQL) { - return Promise.reject(new Error('Unknown database.')); - } - - const sql = db === MYSQL ? query.replace(/\$[0-9]+/g, '?') : query; - - return prisma.rawQuery(sql, params); -} - -export default { - ...prisma, - getDateQuery, - getTimestampInterval, - getFilterQuery, - getEventDataFilterQuery, - toUuid, - parseFilters, - rawQuery, -}; diff --git a/lib/types.ts b/lib/types.ts deleted file mode 100644 index 37c1ffdc..00000000 --- a/lib/types.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { NextApiRequest } from 'next'; -import { EVENT_DATA_TYPE, EVENT_TYPE, KAFKA_TOPIC, ROLES } from './constants'; - -type ObjectValues = T[keyof T]; - -export type Roles = ObjectValues; - -export type EventTypes = ObjectValues; - -export type EventDataTypes = ObjectValues; - -export type KafkaTopics = ObjectValues; - -export interface EventData { - [key: string]: number | string | EventData | number[] | string[] | EventData[]; -} - -export interface Auth { - user?: { - id: string; - username: string; - role: string; - isAdmin: boolean; - }; - shareToken?: { - websiteId: string; - }; -} - -export interface NextApiRequestQueryBody extends NextApiRequest { - auth?: Auth; - query: TQuery & { [key: string]: string | string[] }; - body: TBody; - headers: any; -} - -export interface NextApiRequestAuth extends NextApiRequest { - auth?: Auth; - headers: any; -} - -export interface User { - id: string; - username: string; - password?: string; - role: string; - createdAt?: Date; -} - -export interface Website { - id: string; - userId: string; - resetAt: Date; - name: string; - domain: string; - shareId: string; - createdAt: Date; -} - -export interface Share { - id: string; - token: string; -} - -export interface WebsiteActive { - x: number; -} - -export interface WebsiteMetric { - x: string; - y: number; -} - -export interface WebsiteMetricFilter { - domain?: string; - url?: string; - referrer?: string; - title?: string; - query?: string; - event?: string; - os?: string; - browser?: string; - device?: string; - country?: string; - region?: string; - city?: string; -} - -export interface WebsiteEventMetric { - x: string; - t: string; - y: number; -} - -export interface WebsiteEventDataMetric { - x: string; - t: string; - eventName?: string; - urlPath?: string; -} - -export interface WebsitePageviews { - pageviews: { - t: string; - y: number; - }; - sessions: { - t: string; - y: number; - }; -} - -export interface WebsiteStats { - pageviews: { value: number; change: number }; - uniques: { value: number; change: number }; - bounces: { value: number; change: number }; - totalTime: { value: number; change: number }; -} - -export interface RealtimeInit { - websites: Website[]; - token: string; - data: RealtimeUpdate; -} - -export interface RealtimeUpdate { - pageviews: any[]; - sessions: any[]; - events: any[]; - timestamp: number; -} diff --git a/next.config.js b/next.config.js index 8efb45bc..cc3cde7c 100644 --- a/next.config.js +++ b/next.config.js @@ -1,16 +1,15 @@ /* eslint-disable @typescript-eslint/no-var-requires */ require('dotenv').config(); +const path = require('path'); const pkg = require('./package.json'); -const CLOUD_URL = 'https://cloud.umami.is'; - const contentSecurityPolicy = ` default-src 'self'; img-src *; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' api.umami.is; - frame-ancestors 'self'; + frame-ancestors 'self' ${process.env.ALLOWED_FRAME_URLS}; `; const headers = [ @@ -60,12 +59,14 @@ if (process.env.TRACKER_SCRIPT_NAME) { const redirects = [ { source: '/settings', - destination: process.env.CLOUD_MODE ? '/settings/profile' : '/settings/websites', + destination: process.env.CLOUD_MODE + ? `${process.env.CLOUD_URL}/settings/websites` + : '/settings/websites', permanent: true, }, ]; -if (process.env.CLOUD_MODE && process.env.DISABLE_LOGIN && process.env.CLOUD_URL) { +if (process.env.CLOUD_MODE && process.env.CLOUD_URL && process.env.DISABLE_LOGIN) { redirects.push({ source: '/login', destination: process.env.CLOUD_URL, @@ -75,7 +76,11 @@ if (process.env.CLOUD_MODE && process.env.DISABLE_LOGIN && process.env.CLOUD_URL const config = { env: { + cloudMode: process.env.CLOUD_MODE, + cloudUrl: process.env.CLOUD_URL, + configUrl: '/config', currentVersion: pkg.version, + defaultLocale: process.env.DEFAULT_LOCALE, isProduction: process.env.NODE_ENV === 'production', }, basePath: process.env.BASE_PATH, @@ -93,6 +98,8 @@ const config = { use: ['@svgr/webpack'], }); + config.resolve.alias['public'] = path.resolve('./public'); + return config; }, async headers() { diff --git a/package.components.json b/package.components.json new file mode 100644 index 00000000..feb3fc2e --- /dev/null +++ b/package.components.json @@ -0,0 +1,23 @@ +{ + "name": "@umami/components", + "version": "0.11.0", + "description": "Umami React components.", + "author": "Mike Cao ", + "license": "MIT", + "type": "module", + "main": "./index.js", + "types": "./index.d.ts", + "peerDependencies": { + "@tanstack/react-query": "^4.33.0", + "classnames": "^2.3.1", + "colord": "^2.9.2", + "immer": "^9.0.12", + "moment-timezone": "^0.5.35", + "next": "^13.4.0", + "next-basics": "^0.36.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-intl": "^5.24.7", + "zustand": "^4.3.8" + } +} diff --git a/package.json b/package.json index c1981e7f..4fda0a22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "umami", - "version": "2.2.0", + "version": "2.6.0", "description": "A simple, fast, privacy-focused alternative to Google Analytics.", "author": "Mike Cao ", "license": "MIT", @@ -11,28 +11,31 @@ }, "scripts": { "dev": "next dev -p 3000", - "build": "npm-run-all build-db check-db build-tracker build-geo build-app", + "build": "npm-run-all check-env build-db check-db build-tracker build-geo build-app", "start": "next start", "build-docker": "npm-run-all build-db build-tracker build-geo build-app", "start-docker": "npm-run-all check-db update-tracker start-server", "start-env": "node scripts/start-env.js", "start-server": "node server.js", "build-app": "next build", - "build-tracker": "rollup -c rollup.tracker.config.js", + "build-components": "rollup -c rollup.components.config.mjs", + "build-tracker": "rollup -c rollup.tracker.config.mjs", "build-db": "npm-run-all copy-db-files build-db-client", - "build-lang": "npm-run-all format-lang compile-lang download-country-names download-language-names", + "build-lang": "npm-run-all format-lang compile-lang clean-lang download-country-names download-language-names", "build-geo": "node scripts/build-geo.js", "build-db-schema": "prisma db pull", "build-db-client": "prisma generate", "update-tracker": "node scripts/update-tracker.js", "update-db": "prisma migrate deploy", "check-db": "node scripts/check-db.js", + "check-env": "node scripts/check-env.js", "copy-db-files": "node scripts/copy-db-files.js", "extract-messages": "formatjs extract \"{pages,components}/**/*.js\" --out-file build/messages.json", "merge-messages": "node scripts/merge-messages.js", "generate-lang": "npm-run-all extract-messages merge-messages", "format-lang": "node scripts/format-lang.js", "compile-lang": "formatjs compile-folder --ast build/messages public/intl/messages", + "clean-lang": "prettier --write ./public/intl/messages/*.json", "check-lang": "node scripts/check-lang.js", "download-country-names": "node scripts/download-country-names.js", "download-language-names": "node scripts/download-language-names.js", @@ -59,10 +62,10 @@ ], "dependencies": { "@fontsource/inter": "^4.5.15", - "@prisma/client": "4.13.0", - "@tanstack/react-query": "^4.16.1", + "@prisma/client": "5.2.0", + "@tanstack/react-query": "^4.33.0", "@umami/prisma-client": "^0.2.0", - "@umami/redis-client": "^0.2.0", + "@umami/redis-client": "^0.5.0", "chalk": "^4.1.1", "chart.js": "^4.2.1", "chartjs-adapter-date-fns": "^3.0.0", @@ -78,7 +81,6 @@ "del": "^6.0.0", "detect-browser": "^5.2.0", "dotenv": "^10.0.0", - "formik": "^2.2.9", "fs-extra": "^10.0.1", "immer": "^9.0.12", "ipaddr.js": "^2.0.1", @@ -89,12 +91,12 @@ "kafkajs": "^2.1.0", "maxmind": "^4.3.6", "moment-timezone": "^0.5.35", - "next": "13.2.4", - "next-basics": "^0.27.0", + "next": "13.4.19", + "next-basics": "^0.36.0", "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "react": "^18.2.0", - "react-basics": "^0.77.0", + "react-basics": "^0.98.0", "react-beautiful-dnd": "^13.1.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.4", @@ -104,24 +106,27 @@ "react-use-measure": "^2.0.4", "react-window": "^1.8.6", "request-ip": "^3.3.0", - "semver": "^7.3.6", + "semver": "^7.5.2", "thenby": "^1.3.4", "timezone-support": "^2.0.2", - "uuid": "^8.3.2", + "uuid": "^9.0.0", "yup": "^0.32.11", - "zustand": "^3.7.2" + "zustand": "^4.3.8" }, "devDependencies": { "@formatjs/cli": "^4.2.29", "@netlify/plugin-nextjs": "^4.27.3", "@rollup/plugin-alias": "^5.0.0", - "@rollup/plugin-buble": "^0.21.3", - "@rollup/plugin-commonjs": "^24.1.0", + "@rollup/plugin-buble": "^1.0.2", + "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.2", - "@rollup/plugin-replace": "^4.0.0", - "@svgr/rollup": "^7.0.0", + "@rollup/plugin-node-resolve": "^15.2.0", + "@rollup/plugin-replace": "^5.0.2", + "@svgr/rollup": "^8.1.0", "@svgr/webpack": "^6.2.1", + "@types/node": "^18.11.9", + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.8", "@typescript-eslint/eslint-plugin": "^5.50.0", "@typescript-eslint/parser": "^5.50.0", "cross-env": "^7.0.3", @@ -141,21 +146,22 @@ "postcss-preset-env": "7.8.3", "postcss-rtlcss": "^4.0.1", "prettier": "^2.6.2", - "prisma": "4.13.0", + "prisma": "5.2.0", "prompts": "2.4.2", - "rollup": "^2.70.1", + "rollup": "^3.28.0", + "rollup-plugin-copy": "^3.4.0", "rollup-plugin-delete": "^2.0.0", - "rollup-plugin-dts": "^5.3.0", + "rollup-plugin-dts": "^5.3.1", "rollup-plugin-esbuild": "^5.0.0", - "rollup-plugin-node-externals": "^5.1.2", + "rollup-plugin-node-externals": "^6.1.1", "rollup-plugin-postcss": "^4.0.2", "rollup-plugin-terser": "^7.0.2", - "stylelint": "^14.16.1", + "stylelint": "^15.10.1", "stylelint-config-css-modules": "^4.1.0", "stylelint-config-prettier": "^9.0.3", "stylelint-config-recommended": "^9.0.0", "tar": "^6.1.2", "ts-node": "^10.9.1", - "typescript": "^4.9.5" + "typescript": "^5.1.6" } } diff --git a/pages/_app.js b/pages/_app.js deleted file mode 100644 index fa5efc61..00000000 --- a/pages/_app.js +++ /dev/null @@ -1,62 +0,0 @@ -import { IntlProvider } from 'react-intl'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import Head from 'next/head'; -import Script from 'next/script'; -import { useRouter } from 'next/router'; -import ErrorBoundary from 'components/common/ErrorBoundary'; -import useLocale from 'hooks/useLocale'; -import useConfig from 'hooks/useConfig'; -import '@fontsource/inter/400.css'; -import '@fontsource/inter/700.css'; -import 'react-basics/dist/styles.css'; -import 'styles/variables.css'; -import 'styles/locale.css'; -import 'styles/index.css'; -import 'chartjs-adapter-date-fns'; - -const client = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - refetchOnWindowFocus: false, - }, - }, -}); - -export default function App({ Component, pageProps }) { - const { locale, messages } = useLocale(); - const { basePath, pathname } = useRouter(); - const config = useConfig(); - - const Wrapper = ({ children }) => {children}; - - if (config?.uiDisabled) { - return null; - } - - return ( - - null} - > - - - - - - - - - - - - - {!pathname.includes('/share/') && `; diff --git a/components/pages/settings/websites/WebsiteAddForm.js b/src/components/pages/settings/websites/WebsiteAddForm.js similarity index 93% rename from components/pages/settings/websites/WebsiteAddForm.js rename to src/components/pages/settings/websites/WebsiteAddForm.js index 77b850b4..371343ba 100644 --- a/components/pages/settings/websites/WebsiteAddForm.js +++ b/src/components/pages/settings/websites/WebsiteAddForm.js @@ -7,9 +7,9 @@ import { Button, SubmitButton, } from 'react-basics'; -import useApi from 'hooks/useApi'; +import useApi from 'components/hooks/useApi'; import { DOMAIN_REGEX } from 'lib/constants'; -import useMessages from 'hooks/useMessages'; +import useMessages from 'components/hooks/useMessages'; export function WebsiteAddForm({ onSave, onClose }) { const { formatMessage, labels, messages } = useMessages(); diff --git a/components/pages/settings/websites/WebsiteData.js b/src/components/pages/settings/websites/WebsiteData.js similarity index 96% rename from components/pages/settings/websites/WebsiteData.js rename to src/components/pages/settings/websites/WebsiteData.js index a2bc6bfa..08d6702e 100644 --- a/components/pages/settings/websites/WebsiteData.js +++ b/src/components/pages/settings/websites/WebsiteData.js @@ -1,7 +1,7 @@ import { Button, Modal, ModalTrigger, ActionForm } from 'react-basics'; import WebsiteDeleteForm from 'components/pages/settings/websites/WebsiteDeleteForm'; import WebsiteResetForm from 'components/pages/settings/websites/WebsiteResetForm'; -import useMessages from 'hooks/useMessages'; +import useMessages from 'components/hooks/useMessages'; export function WebsiteData({ websiteId, onSave }) { const { formatMessage, labels, messages } = useMessages(); diff --git a/components/pages/settings/websites/WebsiteDeleteForm.js b/src/components/pages/settings/websites/WebsiteDeleteForm.js similarity index 92% rename from components/pages/settings/websites/WebsiteDeleteForm.js rename to src/components/pages/settings/websites/WebsiteDeleteForm.js index c9e302fc..1548bddb 100644 --- a/components/pages/settings/websites/WebsiteDeleteForm.js +++ b/src/components/pages/settings/websites/WebsiteDeleteForm.js @@ -7,8 +7,8 @@ import { SubmitButton, TextField, } from 'react-basics'; -import useApi from 'hooks/useApi'; -import useMessages from 'hooks/useMessages'; +import useApi from 'components/hooks/useApi'; +import useMessages from 'components/hooks/useMessages'; const CONFIRM_VALUE = 'DELETE'; diff --git a/components/pages/settings/websites/WebsiteEditForm.js b/src/components/pages/settings/websites/WebsiteEditForm.js similarity index 94% rename from components/pages/settings/websites/WebsiteEditForm.js rename to src/components/pages/settings/websites/WebsiteEditForm.js index 89c62889..18ad0ac9 100644 --- a/components/pages/settings/websites/WebsiteEditForm.js +++ b/src/components/pages/settings/websites/WebsiteEditForm.js @@ -1,8 +1,8 @@ import { SubmitButton, Form, FormInput, FormRow, FormButtons, TextField } from 'react-basics'; import { useRef } from 'react'; -import useApi from 'hooks/useApi'; +import useApi from 'components/hooks/useApi'; import { DOMAIN_REGEX } from 'lib/constants'; -import useMessages from 'hooks/useMessages'; +import useMessages from 'components/hooks/useMessages'; export function WebsiteEditForm({ websiteId, data, onSave }) { const { formatMessage, labels, messages } = useMessages(); diff --git a/components/pages/settings/websites/WebsiteResetForm.js b/src/components/pages/settings/websites/WebsiteResetForm.js similarity index 75% rename from components/pages/settings/websites/WebsiteResetForm.js rename to src/components/pages/settings/websites/WebsiteResetForm.js index 4ac24169..9886429b 100644 --- a/components/pages/settings/websites/WebsiteResetForm.js +++ b/src/components/pages/settings/websites/WebsiteResetForm.js @@ -7,13 +7,13 @@ import { SubmitButton, TextField, } from 'react-basics'; -import useApi from 'hooks/useApi'; -import useMessages from 'hooks/useMessages'; +import useApi from 'components/hooks/useApi'; +import useMessages from 'components/hooks/useMessages'; const CONFIRM_VALUE = 'RESET'; export function WebsiteResetForm({ websiteId, onSave, onClose }) { - const { formatMessage, labels, messages } = useMessages(); + const { formatMessage, labels, messages, FormattedMessage } = useMessages(); const { post, useMutation } = useApi(); const { mutate, error } = useMutation(data => post(`/websites/${websiteId}/reset`, data)); @@ -28,7 +28,12 @@ export function WebsiteResetForm({ websiteId, onSave, onClose }) { return (
-

{formatMessage(messages.resetWebsite, { confirmation: CONFIRM_VALUE })}

+

+ {CONFIRM_VALUE} }} + /> +

value === CONFIRM_VALUE }}> diff --git a/components/pages/settings/websites/WebsiteSettings.js b/src/components/pages/settings/websites/WebsiteSettings.js similarity index 80% rename from components/pages/settings/websites/WebsiteSettings.js rename to src/components/pages/settings/websites/WebsiteSettings.js index 0a70a731..f73e0a87 100644 --- a/components/pages/settings/websites/WebsiteSettings.js +++ b/src/components/pages/settings/websites/WebsiteSettings.js @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Breadcrumbs, Item, Tabs, useToast, Button, Text, Icon, Icons } from 'react-basics'; +import { Item, Tabs, useToasts, Button, Text, Icon, Icons } from 'react-basics'; import { useRouter } from 'next/router'; import Link from 'next/link'; import Page from 'components/layout/Page'; @@ -8,16 +8,14 @@ import WebsiteEditForm from 'components/pages/settings/websites/WebsiteEditForm' import WebsiteData from 'components/pages/settings/websites/WebsiteData'; import TrackingCode from 'components/pages/settings/websites/TrackingCode'; import ShareUrl from 'components/pages/settings/websites/ShareUrl'; -import useApi from 'hooks/useApi'; -import useMessages from 'hooks/useMessages'; -import useConfig from 'hooks/useConfig'; +import useApi from 'components/hooks/useApi'; +import useMessages from 'components/hooks/useMessages'; -export function WebsiteSettings({ websiteId }) { +export function WebsiteSettings({ websiteId, openExternal = false }) { const router = useRouter(); const { formatMessage, labels, messages } = useMessages(); - const { openExternal } = useConfig(); const { get, useQuery } = useApi(); - const { toast, showToast } = useToast(); + const { showToast } = useToasts(); const { data, isLoading } = useQuery( ['website', websiteId], () => get(`/websites/${websiteId}`), @@ -51,17 +49,7 @@ export function WebsiteSettings({ websiteId }) { return ( - {toast} - - - {formatMessage(labels.websites)} - - {values?.name} - - } - > + + + {close => } + + + )} + + ); + + return ( + + {showHeader && {addButton}} + + + ); +} + +export default WebsitesList; diff --git a/src/components/pages/settings/websites/WebsitesTable.js b/src/components/pages/settings/websites/WebsitesTable.js new file mode 100644 index 00000000..7fa50716 --- /dev/null +++ b/src/components/pages/settings/websites/WebsitesTable.js @@ -0,0 +1,89 @@ +import Link from 'next/link'; +import { Button, Text, Icon, Icons } from 'react-basics'; +import SettingsTable from 'components/common/SettingsTable'; +import Empty from 'components/common/Empty'; +import useMessages from 'components/hooks/useMessages'; +import useUser from 'components/hooks/useUser'; + +export function WebsitesTable({ + data = [], + filterValue, + onFilterChange, + onPageChange, + onPageSizeChange, + showTeam, + showEditButton, + openExternal = false, +}) { + const { formatMessage, labels } = useMessages(); + const { user } = useUser(); + + const showTable = data && (filterValue || data?.data?.length !== 0); + + const teamColumns = [ + { name: 'teamName', label: formatMessage(labels.teamName) }, + { name: 'owner', label: formatMessage(labels.owner) }, + ]; + + const columns = [ + { name: 'name', label: formatMessage(labels.name) }, + { name: 'domain', label: formatMessage(labels.domain) }, + ...(showTeam ? teamColumns : []), + { name: 'action', label: ' ' }, + ]; + + return ( + <> + {showTable && ( + + {row => { + const { + id, + teamWebsite, + user: { username, id: ownerId }, + } = row; + if (showTeam) { + row.teamName = teamWebsite[0]?.team.name; + row.owner = username; + } + + return ( + <> + {showEditButton && (!showTeam || ownerId === user.id) && ( + + + + )} + + + + + ); + }} + + )} + {!showTable && } + + ); +} + +export default WebsitesTable; diff --git a/components/pages/settings/websites/WebsitesTable.module.css b/src/components/pages/settings/websites/WebsitesTable.module.css similarity index 100% rename from components/pages/settings/websites/WebsitesTable.module.css rename to src/components/pages/settings/websites/WebsitesTable.module.css diff --git a/src/components/pages/websites/WebsiteChart.js b/src/components/pages/websites/WebsiteChart.js new file mode 100644 index 00000000..7e20e785 --- /dev/null +++ b/src/components/pages/websites/WebsiteChart.js @@ -0,0 +1,51 @@ +import { useMemo } from 'react'; +import PageviewsChart from 'components/metrics/PageviewsChart'; +import { useApi, useDateRange, useTimezone, usePageQuery } from 'components/hooks'; +import { getDateArray } from 'lib/date'; + +export function WebsiteChart({ websiteId }) { + const [dateRange] = useDateRange(websiteId); + const { startDate, endDate, unit, modified } = dateRange; + const [timezone] = useTimezone(); + const { + query: { url, referrer, os, browser, device, country, region, city, title }, + } = usePageQuery(); + const { get, useQuery } = useApi(); + + const { data, isLoading } = useQuery( + [ + 'websites:pageviews', + { websiteId, modified, url, referrer, os, browser, device, country, region, city, title }, + ], + () => + get(`/websites/${websiteId}/pageviews`, { + startAt: +startDate, + endAt: +endDate, + unit, + timezone, + url, + referrer, + os, + browser, + device, + country, + region, + city, + title, + }), + ); + + const chartData = useMemo(() => { + if (data) { + return { + pageviews: getDateArray(data.pageviews, startDate, endDate, unit), + sessions: getDateArray(data.sessions, startDate, endDate, unit), + }; + } + return { pageviews: [], sessions: [] }; + }, [data, startDate, endDate, unit]); + + return ; +} + +export default WebsiteChart; diff --git a/src/components/pages/websites/WebsiteChart.module.css b/src/components/pages/websites/WebsiteChart.module.css new file mode 100644 index 00000000..b795047a --- /dev/null +++ b/src/components/pages/websites/WebsiteChart.module.css @@ -0,0 +1,17 @@ +.container { + position: relative; + display: flex; + flex-direction: column; + align-self: stretch; +} + +.chart { + position: relative; + overflow: hidden; +} + +.title { + font-size: var(--font-size-lg); + line-height: 60px; + font-weight: 600; +} diff --git a/src/components/pages/websites/WebsiteChartList.js b/src/components/pages/websites/WebsiteChartList.js new file mode 100644 index 00000000..56cbe157 --- /dev/null +++ b/src/components/pages/websites/WebsiteChartList.js @@ -0,0 +1,50 @@ +import { Button, Text, Icon } from 'react-basics'; +import { useMemo } from 'react'; +import { firstBy } from 'thenby'; +import Link from 'next/link'; +import WebsiteChart from 'components/pages/websites/WebsiteChart'; +import useDashboard from 'store/dashboard'; +import styles from './WebsiteList.module.css'; +import WebsiteHeader from './WebsiteHeader'; +import { WebsiteMetricsBar } from './WebsiteMetricsBar'; +import { useMessages, useLocale } from 'components/hooks'; +import Icons from 'components/icons'; + +export default function WebsiteChartList({ websites, showCharts, limit }) { + const { formatMessage, labels } = useMessages(); + const { websiteOrder } = useDashboard(); + const { dir } = useLocale(); + + const ordered = useMemo( + () => + websites + .map(website => ({ ...website, order: websiteOrder.indexOf(website.id) || 0 })) + .sort(firstBy('order')), + [websites, websiteOrder], + ); + + return ( +
+ {ordered.map(({ id }, index) => { + return index < limit ? ( +
+ + + + + + + {showCharts && } +
+ ) : null; + })} +
+ ); +} diff --git a/src/components/pages/websites/WebsiteDetailsPage.js b/src/components/pages/websites/WebsiteDetailsPage.js new file mode 100644 index 00000000..222d94d9 --- /dev/null +++ b/src/components/pages/websites/WebsiteDetailsPage.js @@ -0,0 +1,40 @@ +import { Loading } from 'react-basics'; +import { useRouter } from 'next/router'; +import Page from 'components/layout/Page'; +import WebsiteChart from 'components/pages/websites/WebsiteChart'; +import FilterTags from 'components/metrics/FilterTags'; +import usePageQuery from 'components/hooks/usePageQuery'; +import WebsiteTableView from './WebsiteTableView'; +import WebsiteMenuView from './WebsiteMenuView'; +import { useWebsite } from 'components/hooks'; +import WebsiteHeader from './WebsiteHeader'; +import { WebsiteMetricsBar } from './WebsiteMetricsBar'; + +export default function WebsiteDetailsPage({ websiteId }) { + const { data: website, isLoading, error } = useWebsite(websiteId); + const { pathname } = useRouter(); + const showLinks = !pathname.includes('/share/'); + + const { + query: { view, url, referrer, os, browser, device, country, region, city, title }, + } = usePageQuery(); + + return ( + + + + + + {!website && } + {website && ( + <> + {!view && } + {view && } + + )} + + ); +} diff --git a/src/components/pages/websites/WebsiteEventData.js b/src/components/pages/websites/WebsiteEventData.js new file mode 100644 index 00000000..d38ca1ad --- /dev/null +++ b/src/components/pages/websites/WebsiteEventData.js @@ -0,0 +1,41 @@ +import { Flexbox, Loading } from 'react-basics'; +import EventDataTable from 'components/pages/event-data/EventDataTable'; +import EventDataValueTable from 'components/pages/event-data/EventDataValueTable'; +import { EventDataMetricsBar } from 'components/pages/event-data/EventDataMetricsBar'; +import { useDateRange, useApi, usePageQuery } from 'components/hooks'; +import styles from './WebsiteEventData.module.css'; + +function useData(websiteId, event) { + const [dateRange] = useDateRange(websiteId); + const { startDate, endDate } = dateRange; + const { get, useQuery } = useApi(); + const { data, error, isLoading } = useQuery( + ['event-data:events', { websiteId, startDate, endDate, event }], + () => + get('/event-data/events', { + websiteId, + startAt: +startDate, + endAt: +endDate, + event, + }), + { enabled: !!(websiteId && startDate && endDate) }, + ); + + return { data, error, isLoading }; +} + +export default function WebsiteEventData({ websiteId }) { + const { + query: { event }, + } = usePageQuery(); + const { data, isLoading } = useData(websiteId, event); + + return ( + + + {!event && } + {isLoading && } + {event && data && } + + ); +} diff --git a/src/components/pages/websites/WebsiteEventData.module.css b/src/components/pages/websites/WebsiteEventData.module.css new file mode 100644 index 00000000..1d178231 --- /dev/null +++ b/src/components/pages/websites/WebsiteEventData.module.css @@ -0,0 +1,7 @@ +.container a { + color: var(--font-color100); +} + +.container a:hover { + color: var(--primary400); +} diff --git a/src/components/pages/websites/WebsiteEventDataPage.js b/src/components/pages/websites/WebsiteEventDataPage.js new file mode 100644 index 00000000..08acafb5 --- /dev/null +++ b/src/components/pages/websites/WebsiteEventDataPage.js @@ -0,0 +1,12 @@ +import Page from 'components/layout/Page'; +import WebsiteHeader from './WebsiteHeader'; +import WebsiteEventData from './WebsiteEventData'; + +export default function WebsiteEventDataPage({ websiteId }) { + return ( + + + + + ); +} diff --git a/src/components/pages/websites/WebsiteHeader.js b/src/components/pages/websites/WebsiteHeader.js new file mode 100644 index 00000000..fb4e0986 --- /dev/null +++ b/src/components/pages/websites/WebsiteHeader.js @@ -0,0 +1,75 @@ +import classNames from 'classnames'; +import { Row, Column, Text, Button, Icon } from 'react-basics'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import Favicon from 'components/common/Favicon'; +import ActiveUsers from 'components/metrics/ActiveUsers'; +import Icons from 'components/icons'; +import { useMessages, useWebsite } from 'components/hooks'; +import styles from './WebsiteHeader.module.css'; + +export function WebsiteHeader({ websiteId, showLinks = true, children }) { + const { formatMessage, labels } = useMessages(); + const { pathname } = useRouter(); + const { data: website } = useWebsite(websiteId); + const { name, domain } = website || {}; + + const links = [ + { + label: formatMessage(labels.overview), + icon: , + path: '', + }, + { + label: formatMessage(labels.realtime), + icon: , + path: '/realtime', + }, + { + label: formatMessage(labels.reports), + icon: , + path: '/reports', + }, + { + label: formatMessage(labels.eventData), + icon: , + path: '/event-data', + }, + ]; + + return ( + + + + {name} + + + + {showLinks && ( +
+ {links.map(({ label, icon, path }) => { + const selected = path ? pathname.endsWith(path) : pathname === '/websites/[id]'; + + return ( + + + + ); + })} +
+ )} + {children} +
+
+ ); +} + +export default WebsiteHeader; diff --git a/src/components/pages/websites/WebsiteHeader.module.css b/src/components/pages/websites/WebsiteHeader.module.css new file mode 100644 index 00000000..93e622d9 --- /dev/null +++ b/src/components/pages/websites/WebsiteHeader.module.css @@ -0,0 +1,55 @@ +.header { + display: flex; + flex-direction: row; + align-items: center; +} + +.title { + display: flex; + flex-direction: row; + align-items: center; + gap: 10px; + font-size: 24px; + font-weight: 700; + overflow: hidden; + height: 100px; +} + +.actions { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-end; + gap: 30px; + min-height: 0; +} + +.selected { + font-weight: bold; +} + +.links { + display: flex; + flex-direction: row; + align-items: center; +} + +@media only screen and (max-width: 768px) { + .links { + justify-content: space-evenly; + flex: 1; + border-bottom: 1px solid var(--base300); + padding-bottom: 10px; + margin-bottom: 10px; + } + + .label { + display: none; + } + + .icon, + .icon svg { + width: 30px; + height: 30px; + } +} diff --git a/components/pages/websites/WebsiteList.module.css b/src/components/pages/websites/WebsiteList.module.css similarity index 100% rename from components/pages/websites/WebsiteList.module.css rename to src/components/pages/websites/WebsiteList.module.css diff --git a/components/pages/websites/WebsiteMenuView.js b/src/components/pages/websites/WebsiteMenuView.js similarity index 94% rename from components/pages/websites/WebsiteMenuView.js rename to src/components/pages/websites/WebsiteMenuView.js index 4f705124..8c74d615 100644 --- a/components/pages/websites/WebsiteMenuView.js +++ b/src/components/pages/websites/WebsiteMenuView.js @@ -15,10 +15,10 @@ import ScreenTable from 'components/metrics/ScreenTable'; import EventsTable from 'components/metrics/EventsTable'; import Icons from 'components/icons'; import SideNav from 'components/layout/SideNav'; -import usePageQuery from 'hooks/usePageQuery'; -import useMessages from 'hooks/useMessages'; +import usePageQuery from 'components/hooks/usePageQuery'; +import useMessages from 'components/hooks/useMessages'; import styles from './WebsiteMenuView.module.css'; -import useLocale from 'hooks/useLocale'; +import useLocale from 'components/hooks/useLocale'; const views = { url: PagesTable, @@ -102,7 +102,7 @@ export default function WebsiteMenuView({ websiteId, websiteDomain }) { }, { key: 'query', - label: formatMessage(labels.query), + label: formatMessage(labels.queryParameters), url: resolveUrl({ view: 'query' }), }, ]; diff --git a/components/pages/websites/WebsiteMenuView.module.css b/src/components/pages/websites/WebsiteMenuView.module.css similarity index 100% rename from components/pages/websites/WebsiteMenuView.module.css rename to src/components/pages/websites/WebsiteMenuView.module.css diff --git a/src/components/pages/websites/WebsiteMetricsBar.js b/src/components/pages/websites/WebsiteMetricsBar.js new file mode 100644 index 00000000..7ba4a801 --- /dev/null +++ b/src/components/pages/websites/WebsiteMetricsBar.js @@ -0,0 +1,170 @@ +import classNames from 'classnames'; +import { useApi, useDateRange, useMessages, usePageQuery, useSticky } from 'components/hooks'; +import WebsiteDateFilter from 'components/input/WebsiteDateFilter'; +import MetricCard from 'components/metrics/MetricCard'; +import MetricsBar from 'components/metrics/MetricsBar'; +import FilterSelectForm from 'components/pages/reports/FilterSelectForm'; +import PopupForm from 'components/pages/reports/PopupForm'; +import { formatShortTime } from 'lib/format'; +import { Button, Column, Icon, Icons, Popup, PopupTrigger, Row } from 'react-basics'; +import styles from './WebsiteMetricsBar.module.css'; + +export function WebsiteMetricsBar({ websiteId, showFilter = true, sticky }) { + const { formatMessage, labels } = useMessages(); + + const { get, useQuery } = useApi(); + const [dateRange] = useDateRange(websiteId); + const { startDate, endDate, modified } = dateRange; + const { ref, isSticky } = useSticky({ enabled: sticky }); + const { + resolveUrl, + router, + query: { url, referrer, title, os, browser, device, country, region, city }, + } = usePageQuery(); + + const { data, error, isLoading, isFetched } = useQuery( + [ + 'websites:stats', + { websiteId, modified, url, referrer, title, os, browser, device, country, region, city }, + ], + () => + get(`/websites/${websiteId}/stats`, { + startAt: +startDate, + endAt: +endDate, + url, + referrer, + title, + os, + browser, + device, + country, + region, + city, + }), + ); + + const fieldOptions = [ + { name: 'url', type: 'string', label: formatMessage(labels.url) }, + { name: 'referrer', type: 'string', label: formatMessage(labels.referrer) }, + { name: 'browser', type: 'string', label: formatMessage(labels.browser) }, + { name: 'os', type: 'string', label: formatMessage(labels.os) }, + { name: 'device', type: 'string', label: formatMessage(labels.device) }, + { name: 'country', type: 'string', label: formatMessage(labels.country) }, + { name: 'region', type: 'string', label: formatMessage(labels.region) }, + { name: 'city', type: 'string', label: formatMessage(labels.city) }, + ]; + + const { pageviews, uniques, bounces, totaltime } = data || {}; + const num = Math.min(data && uniques.value, data && bounces.value); + const diffs = data && { + pageviews: pageviews.value - pageviews.change, + uniques: uniques.value - uniques.change, + bounces: bounces.value - bounces.change, + totaltime: totaltime.value - totaltime.change, + }; + + const handleAddFilter = ({ name, value }) => { + router.push(resolveUrl({ [name]: value })); + }; + + const WebsiteFilterButton = () => { + return ( + + + + {close => { + return ( + + { + handleAddFilter(value); + close(); + }} + allowFilterSelect={false} + /> + + ); + }} + + + ); + }; + + return ( + + + + {!error && isFetched && ( + <> + + + Number(n).toFixed(0) + '%'} + reverseColors + /> + + `${n < 0 ? '-' : ''}${formatShortTime(Math.abs(~~n), ['m', 's'], ' ')}` + } + /> + + )} + + + +
+ {showFilter && } + +
+
+
+ ); +} + +export default WebsiteMetricsBar; diff --git a/components/metrics/WebsiteChart.module.css b/src/components/pages/websites/WebsiteMetricsBar.module.css similarity index 67% rename from components/metrics/WebsiteChart.module.css rename to src/components/pages/websites/WebsiteMetricsBar.module.css index c9334a27..52decfc6 100644 --- a/components/metrics/WebsiteChart.module.css +++ b/src/components/pages/websites/WebsiteMetricsBar.module.css @@ -1,22 +1,4 @@ .container { - position: relative; - display: flex; - flex-direction: column; - align-self: stretch; -} - -.chart { - position: relative; - overflow: hidden; -} - -.title { - font-size: var(--font-size-lg); - line-height: 60px; - font-weight: 600; -} - -.header { display: flex; justify-content: space-between; align-items: center; @@ -35,8 +17,10 @@ gap: 10px; } -.dropdown { - min-width: 200px; +@media only screen and (max-width: 1200px) { + .actions { + margin-top: 40px; + } } @media only screen and (min-width: 992px) { @@ -49,9 +33,3 @@ border-bottom: 1px solid var(--base300); } } - -@media only screen and (max-width: 1200px) { - .actions { - margin-top: 40px; - } -} diff --git a/src/components/pages/websites/WebsiteReportsPage.js b/src/components/pages/websites/WebsiteReportsPage.js new file mode 100644 index 00000000..40631839 --- /dev/null +++ b/src/components/pages/websites/WebsiteReportsPage.js @@ -0,0 +1,56 @@ +import Page from 'components/layout/Page'; +import Empty from 'components/common/Empty'; +import ReportsTable from 'components/pages/reports/ReportsTable'; +import { useMessages, useWebsiteReports } from 'components/hooks'; +import Link from 'next/link'; +import { Button, Flexbox, Icon, Icons, Text } from 'react-basics'; +import WebsiteHeader from './WebsiteHeader'; + +export function WebsiteReportsPage({ websiteId }) { + const { formatMessage, labels } = useMessages(); + const { + reports, + error, + isLoading, + deleteReport, + filter, + handleFilterChange, + handlePageChange, + handlePageSizeChange, + } = useWebsiteReports(websiteId); + + const hasData = (reports && reports.data.length !== 0) || filter; + + const handleDelete = async id => { + await deleteReport(id); + }; + + return ( + + + + + + + + {hasData && ( + + )} + {!hasData && } + + ); +} + +export default WebsiteReportsPage; diff --git a/components/pages/websites/WebsiteTableView.js b/src/components/pages/websites/WebsiteTableView.js similarity index 100% rename from components/pages/websites/WebsiteTableView.js rename to src/components/pages/websites/WebsiteTableView.js diff --git a/components/pages/websites/WebsiteTableView.module.css b/src/components/pages/websites/WebsiteTableView.module.css similarity index 100% rename from components/pages/websites/WebsiteTableView.module.css rename to src/components/pages/websites/WebsiteTableView.module.css diff --git a/src/components/pages/websites/WebsitesPage.js b/src/components/pages/websites/WebsitesPage.js new file mode 100644 index 00000000..61c29448 --- /dev/null +++ b/src/components/pages/websites/WebsitesPage.js @@ -0,0 +1,76 @@ +import Page from 'components/layout/Page'; +import PageHeader from 'components/layout/PageHeader'; +import WebsiteAddForm from 'components/pages/settings/websites/WebsiteAddForm'; +import WebsiteList from 'components/pages/settings/websites/WebsitesList'; +import { useMessages } from 'components/hooks'; +import useUser from 'components/hooks/useUser'; +import { ROLES } from 'lib/constants'; +import { useState } from 'react'; +import { + Button, + Icon, + Icons, + Item, + Modal, + ModalTrigger, + Tabs, + Text, + useToasts, +} from 'react-basics'; + +export function WebsitesPage() { + const { formatMessage, labels, messages } = useMessages(); + const [tab, setTab] = useState('my-websites'); + const [fetch, setFetch] = useState(1); + const { user } = useUser(); + const { showToast } = useToasts(); + const cloudMode = Boolean(process.env.cloudMode); + + const handleSave = async () => { + setFetch(fetch + 1); + showToast({ message: formatMessage(messages.saved), variant: 'success' }); + }; + + const addButton = ( + <> + {user.role !== ROLES.viewOnly && ( + + + + {close => } + + + )} + + ); + + return ( + + {!cloudMode && addButton} + + {formatMessage(labels.myWebsites)} + {formatMessage(labels.teamWebsites)} + + + {tab === 'my-websites' && ( + + )} + {tab === 'team-webaites' && ( + + )} + + ); +} + +export default WebsitesPage; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..f2ef13ca --- /dev/null +++ b/src/index.ts @@ -0,0 +1,117 @@ +/* +export * from 'components/common/ConfirmDeleteForm'; +export * from 'components/common/Empty'; +export * from 'components/common/EmptyPlaceholder'; +export * from 'components/common/ErrorBoundary'; +export * from 'components/common/ErrorMessage'; +export * from 'components/common/Favicon'; +export * from 'components/common/FilterButtons'; +export * from 'components/common/FilterLink'; +export * from 'components/common/HamburgerButton'; +export * from 'components/common/HoverTooltip'; +export * from 'components/common/LinkButton'; +export * from 'components/common/MobileMenu'; +export * from 'components/common/Pager'; +export * from 'components/common/SettingsTable'; +export * from 'components/common/UpdateNotice'; +export * from 'components/common/WorldMap'; + +export * from 'components/hooks/useApi'; +export * from 'components/hooks/useConfig'; +export * from 'components/hooks/useCountryNames'; +export * from 'components/hooks/useDateRange'; +export * from 'components/hooks/useDocumentClick'; +export * from 'components/hooks/useEscapeKey'; +export * from 'components/hooks/useFilters'; +export * from 'components/hooks/useForceUpdate'; +export * from 'components/hooks/useFormat'; +export * from 'components/hooks/useLanguageNames'; +export * from 'components/hooks/useLocale'; +export * from 'components/hooks/useMessages'; +export * from 'components/hooks/usePageQuery'; +export * from 'components/hooks/useReport'; +export * from 'components/hooks/useReports'; +export * from 'components/hooks/useRequireLogin'; +export * from 'components/hooks/useShareToken'; +export * from 'components/hooks/useSticky'; +export * from 'components/hooks/useTheme'; +export * from 'components/hooks/useTimezone'; +export * from 'components/hooks/useUser'; +export * from 'components/hooks/useWebsite'; +export * from 'components/hooks/useWebsiteReports'; + +export * from 'components/input/DateFilter'; +export * from 'components/input/LanguageButton'; +export * from 'components/input/LogoutButton'; +export * from 'components/input/MonthSelect'; +export * from 'components/input/ProfileButton'; +export * from 'components/input/RefreshButton'; +export * from 'components/input/SettingsButton'; +export * from 'components/input/ThemeButton'; +export * from 'components/input/WebsiteDateFilter'; +export * from 'components/input/WebsiteSelect'; + +export * from 'components/layout/AppLayout'; +export * from 'components/layout/Footer'; +export * from 'components/layout/Grid'; +export * from 'components/layout/Header'; +export * from 'components/layout/NavBar'; +export * from 'components/layout/NavGroup'; +export * from 'components/layout/Page'; +export * from 'components/layout/PageHeader'; +export * from 'components/layout/ReportsLayout'; +export * from 'components/layout/SettingsLayout'; +export * from 'components/layout/ShareLayout'; +export * from 'components/layout/SideNav'; +*/ + +export * from 'components/hooks/useApi'; +export * from 'components/hooks/useConfig'; +export * from 'components/hooks/useCountryNames'; +export * from 'components/hooks/useDateRange'; +export * from 'components/hooks/useDocumentClick'; +export * from 'components/hooks/useEscapeKey'; +export * from 'components/hooks/useFilters'; +export * from 'components/hooks/useForceUpdate'; +export * from 'components/hooks/useFormat'; +export * from 'components/hooks/useLanguageNames'; +export * from 'components/hooks/useLocale'; +export * from 'components/hooks/useMessages'; +export * from 'components/hooks/usePageQuery'; +export * from 'components/hooks/useReport'; +export * from 'components/hooks/useReports'; +export * from 'components/hooks/useRequireLogin'; +export * from 'components/hooks/useShareToken'; +export * from 'components/hooks/useSticky'; +export * from 'components/hooks/useTheme'; +export * from 'components/hooks/useTimezone'; +export * from 'components/hooks/useUser'; +export * from 'components/hooks/useWebsite'; +export * from 'components/hooks/useWebsiteReports'; + +export * from 'components/pages/settings/teams/TeamAddForm'; +export * from 'components/pages/settings/teams/TeamAddWebsiteForm'; +export * from 'components/pages/settings/teams/TeamDeleteForm'; +export * from 'components/pages/settings/teams/TeamEditForm'; +export * from 'components/pages/settings/teams/TeamJoinForm'; +export * from 'components/pages/settings/teams/TeamLeaveForm'; +export * from 'components/pages/settings/teams/TeamMemberRemoveButton'; +export * from 'components/pages/settings/teams/TeamMembers'; +export * from 'components/pages/settings/teams/TeamMembersTable'; +export * from 'components/pages/settings/teams/TeamSettings'; +export * from 'components/pages/settings/teams/TeamsList'; +export * from 'components/pages/settings/teams/TeamsTable'; +export * from 'components/pages/settings/teams/TeamWebsiteRemoveButton'; +export * from 'components/pages/settings/teams/TeamWebsites'; +export * from 'components/pages/settings/teams/TeamWebsitesTable'; +export * from 'components/pages/settings/teams/WebsiteTags'; + +export * from 'components/pages/settings/websites/ShareUrl'; +export * from 'components/pages/settings/websites/TrackingCode'; +export * from 'components/pages/settings/websites/WebsiteAddForm'; +export * from 'components/pages/settings/websites/WebsiteDeleteForm'; +export * from 'components/pages/settings/websites/WebsiteEditForm'; +export * from 'components/pages/settings/websites/WebsiteResetForm'; +export * from 'components/pages/settings/websites/WebsiteSettings'; +export * from 'components/pages/settings/websites/WebsitesList'; +export * from 'components/pages/settings/websites/WebsitesTable'; diff --git a/src/lang/am-ET.json b/src/lang/am-ET.json new file mode 100644 index 00000000..7bed1423 --- /dev/null +++ b/src/lang/am-ET.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Access code", + "label.actions": "Actions", + "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "Add website", + "label.admin": "Administrator", + "label.after": "After", + "label.all": "All", + "label.all-time": "All time", + "label.analytics": "Analytics", + "label.average": "Average", + "label.average-visit-time": "Average visit time", + "label.back": "Back", + "label.before": "Before", + "label.bounce-rate": "Bounce rate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Browsers", + "label.cancel": "Cancel", + "label.change-password": "Change password", + "label.cities": "Cities", + "label.city": "City", + "label.clear-all": "Clear all", + "label.confirm": "Confirm", + "label.confirm-password": "Confirm password", + "label.contains": "Contains", + "label.continue": "Continue", + "label.countries": "Countries", + "label.country": "Country", + "label.create-report": "Create report", + "label.create-team": "Create team", + "label.create-user": "Create user", + "label.created": "Created", + "label.current-password": "Current password", + "label.custom-range": "Custom range", + "label.dashboard": "Dashboard", + "label.data": "Data", + "label.date": "Date", + "label.date-range": "Date range", + "label.day": "Day", + "label.default-date-range": "Default date range", + "label.delete": "Delete", + "label.delete-team": "Delete team", + "label.delete-user": "Delete user", + "label.delete-website": "Delete website", + "label.description": "Description", + "label.desktop": "Desktop", + "label.details": "Details", + "label.device": "Device", + "label.devices": "Devices", + "label.dismiss": "Dismiss", + "label.does-not-contain": "Does not contain", + "label.domain": "Domain", + "label.dropoff": "Dropoff", + "label.edit": "Edit", + "label.edit-dashboard": "Edit dashboard", + "label.enable-share-url": "Enable share URL", + "label.event": "Event", + "label.event-data": "Event Data", + "label.events": "Events", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", + "label.filter-combined": "Combined", + "label.filter-raw": "Raw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Join", + "label.join-team": "Join team", + "label.language": "Language", + "label.languages": "Languages", + "label.laptop": "Laptop", + "label.last-days": "Last {x} days", + "label.last-hours": "Last {x} hours", + "label.leave": "Leave", + "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", + "label.login": "Login", + "label.logout": "Logout", + "label.max": "Max", + "label.members": "Members", + "label.min": "Min", + "label.mobile": "Mobile", + "label.more": "More", + "label.my-websites": "My websites", + "label.name": "Name", + "label.new-password": "New password", + "label.none": "None", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Page views", + "label.pageTitle": "Page title", + "label.pages": "Pages", + "label.password": "Password", + "label.powered-by": "Powered by {name}", + "label.profile": "Profile", + "label.queries": "Queries", + "label.query": "Query", + "label.query-parameters": "Query parameters", + "label.realtime": "Realtime", + "label.referrer": "Referrer", + "label.referrers": "Referrers", + "label.refresh": "Refresh", + "label.regenerate": "Regenerate", + "label.region": "Region", + "label.regions": "Regions", + "label.remove": "Remove", + "label.reports": "Reports", + "label.required": "Required", + "label.reset": "Reset", + "label.reset-website": "Reset statistics", + "label.retention": "Retention", + "label.role": "Role", + "label.run-query": "Run query", + "label.save": "Save", + "label.screens": "Screens", + "label.select-date": "Select date", + "label.select-website": "Select website", + "label.sessions": "Sessions", + "label.settings": "Settings", + "label.share-url": "Share URL", + "label.single-day": "Single day", + "label.sum": "Sum", + "label.tablet": "Tablet", + "label.team": "Team", + "label.team-guest": "Team guest", + "label.team-id": "Team ID", + "label.team-member": "Team member", + "label.team-name": "Team name", + "label.team-owner": "Team owner", + "label.team-websites": "Team websites", + "label.teams": "Teams", + "label.theme": "Theme", + "label.this-month": "This month", + "label.this-week": "This week", + "label.this-year": "This year", + "label.timezone": "Timezone", + "label.title": "Title", + "label.today": "Today", + "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Tracking code", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", + "label.unique-visitors": "Unique visitors", + "label.unknown": "Unknown", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "User", + "label.username": "Username", + "label.users": "Users", + "label.value": "Value", + "label.view": "View", + "label.view-details": "View details", + "label.view-only": "View only", + "label.views": "Views", + "label.visitors": "Visitors", + "label.website": "Website", + "label.website-id": "Website ID", + "label.websites": "Websites", + "label.window": "Window", + "label.yesterday": "Yesterday", + "message.active-users": "{x} current {x, plural, one {visitor} other {visitors}}", + "message.confirm-delete": "Are you sure you want to delete {target}?", + "message.confirm-leave": "Are you sure you want to leave {target}?", + "message.confirm-reset": "Are you sure you want to reset {target}'s statistics?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", + "message.delete-website-warning": "All website data will be deleted.", + "message.error": "Something went wrong.", + "message.event-log": "{event} on {url}", + "message.go-to-settings": "Go to settings", + "message.incorrect-username-password": "Incorrect username/password.", + "message.invalid-domain": "Invalid domain. Do not include http/https.", + "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", + "message.no-data-available": "No data available.", + "message.no-event-data": "No event data is available.", + "message.no-match-password": "Passwords do not match.", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", + "message.no-teams": "You have not created any teams.", + "message.no-users": "There are no users.", + "message.no-websites-configured": "You do not have any websites configured.", + "message.page-not-found": "Page not found.", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", + "message.reset-website-warning": "All statistics for this website will be deleted, but your settings will remain intact.", + "message.saved": "Saved.", + "message.share-url": "This is the publicly shared URL for {target}.", + "message.team-already-member": "You are already a member of the team.", + "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", + "message.tracking-code": "To track stats for this website, place the following code in the ... section of your HTML.", + "message.user-deleted": "User deleted.", + "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}" +} diff --git a/lang/ar-SA.json b/src/lang/ar-SA.json similarity index 71% rename from lang/ar-SA.json rename to src/lang/ar-SA.json index 6bb39439..0efdfee7 100644 --- a/lang/ar-SA.json +++ b/src/lang/ar-SA.json @@ -2,23 +2,34 @@ "label.access-code": "كود الدعوة", "label.actions": "الإجراءات", "label.activity-log": "سجل الأحداث", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "إضافة موقع", "label.admin": "مدير", + "label.after": "After", "label.all": "الكل", "label.all-time": "كل الوقت", "label.analytics": "تحليلات", + "label.average": "Average", "label.average-visit-time": "متوسط وقت الزيارة", "label.back": "للخلف", + "label.before": "Before", "label.bounce-rate": "معدل الارتداد", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "المتصفحات", "label.cancel": "إلغاء", "label.change-password": "تغيير كلمة المرور", "label.cities": "المدن", + "label.city": "City", "label.clear-all": "مسح الكل", "label.confirm": "تأكيد", "label.confirm-password": "تأكيد كلمة المرور", + "label.contains": "Contains", "label.continue": "متابعة", "label.countries": "الدول", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "انشاء مجموعة", "label.create-user": "انشاء مستخدم", "label.created": "تم الانشاء", @@ -26,23 +37,43 @@ "label.custom-range": "فترة مخصصة", "label.dashboard": "الشاشة الرئيسية", "label.data": "البيانات", + "label.date": "Date", "label.date-range": "فترة مخصصة", + "label.day": "Day", "label.default-date-range": "الفترة المخصصة الافتراضية", "label.delete": "حذف", "label.delete-team": "حذف مجموعة", "label.delete-user": "جذف مستخدم", "label.delete-website": "حذف الموقع", + "label.description": "Description", "label.desktop": "كمبيوتر", "label.details": "تفاصيل", + "label.device": "Device", "label.devices": "الأجهزة", "label.dismiss": "اخفاء", + "label.does-not-contain": "Does not contain", "label.domain": "النطاق", + "label.dropoff": "Dropoff", "label.edit": "تعديل", "label.edit-dashboard": "تعديل لوحة التحكم", "label.enable-share-url": "تفعيل مشاركة الرابط", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "الأحداث", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "مجمعة", "label.filter-raw": "مفصلة", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "انضمام", "label.join-team": "الانضمام للمجموعة", "label.language": "اللغة", @@ -52,46 +83,64 @@ "label.last-hours": "اخر {x} ساعة/ساعات", "label.leave": "مغادرة", "label.leave-team": "مغادرة المجموعة", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "تسجيل الدخول", "label.logout": "تسجيل الخروج", + "label.max": "Max", "label.members": "الأعضاء", + "label.min": "Min", "label.mobile": "جوال", "label.more": "المزيد", + "label.my-websites": "My websites", "label.name": "الإسم", "label.new-password": "كلمة مرور جديدة", "label.none": "غير معرف", - "label.operating-systems": "نظام التشغيل", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "المالك", + "label.page-of": "Page {current} of {total}", "label.page-views": "مشاهدات الصفحة", + "label.pageTitle": "Page title", "label.pages": "الصفحات", "label.password": "كلمة المرور", "label.powered-by": "مشغل بواسطة {name}", "label.profile": "الملف الشخصي", "label.queries": "استعلامات", + "label.query": "Query", "label.query-parameters": "متغيرات الرابط", "label.realtime": "الوقت الفعلي", + "label.referrer": "Referrer", "label.referrers": "التحويلات", "label.refresh": "تحديث", "label.regenerate": "اعادة انشاء", + "label.region": "Region", "label.regions": "المناطق", "label.remove": "إزالة", + "label.reports": "Reports", "label.required": "اجباري", "label.reset": "اعادة تعيين", "label.reset-website": "اعادة تعيين الإحصائيات", + "label.retention": "Retention", "label.role": "الصلاحية", + "label.run-query": "Run query", "label.save": "حفظ", "label.screens": "الشاشات", + "label.select-date": "Select date", "label.select-website": "اختيار موقع", "label.sessions": "الزيارات", "label.settings": "اعدادات", "label.share-url": "مشاركة الرابط", "label.single-day": "يوم واحد", + "label.sum": "Sum", "label.tablet": "تابلت", "label.team": "مجموعة", "label.team-guest": "زائر للمجموعة", "label.team-id": "معرف المجموعة", "label.team-member": "عضو المجموعة", + "label.team-name": "Team name", "label.team-owner": "مدير المجموعة", + "label.team-websites": "Team websites", "label.teams": "المجموعات", "label.theme": "المظهر", "label.this-month": "الشهر الحالي", @@ -101,24 +150,37 @@ "label.title": "العنوان", "label.today": "اليوم", "label.toggle-charts": "تغيير الإحصائيات", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "كود التتبع", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "زائرون فريدون", "label.unknown": "غير معروف", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "مستخدم", "label.username": "اسم المستخدم", "label.users": "المستخدمين", + "label.value": "Value", "label.view": "عرض", "label.view-details": "عرض التفاصيل", + "label.view-only": "View only", "label.views": "المشاهدات", "label.visitors": "الزوار", + "label.website": "Website", "label.website-id": "معرف الموقع", "label.websites": "المواقع", + "label.window": "Window", "label.yesterday": "الأمس", "message.active-users": "{x} حاليا {x, plural, one {زائر واحد} other {زوار}}", "message.confirm-delete": "هل أنت متأكد من حذف {target}?", "message.confirm-leave": "هل أنت متأكد من مغادرة {target}?", "message.confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟", - "message.delete-website": "حذف الموقع", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "كافة البيانات المرتبطة سيم حذفها ايضا.", "message.error": "حدث خطأ ما.", "message.event-log": "{event} في {url}", @@ -126,21 +188,24 @@ "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.no-data-available": "لا توجد بيانات متاحة.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "كلمة المرور غير متطابقة", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "هذه المجموعة ليس لديه اي موقع.", "message.no-teams": "لم تقم بإنشاء اي مجموعة.", "message.no-users": "لا يوجد مستخدمين.", + "message.no-websites-configured": "لم تقم بإعداد اي موقع.", "message.page-not-found": "الصفحة غير موجودة.", - "message.reset-website": "اعادة تعيين الإحصائيات", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "سيتم اعادة تعيين كافة الإحصائيات لهذا الموقع، لكن لن يتم تعيير كود التتبع", "message.saved": "تم الحفظ بنجاح.", "message.share-url": "هذا الرابط الذي تم مشاركته بشكل عام لـ {target}.", "message.team-already-member": "أنت عضو في المجموعة", "message.team-not-found": "لم يتم العثور على المجموعة", + "message.team-websites-info": "يمكن مشاهدة الموقع من اي عضو في المجموعة.", "message.tracking-code": "كود التتبع", "message.user-deleted": "تم حذف المستخدم.", - "message.visitor-log": "زائر من {country} يستخدم {browser} على {os} {device}", - "messages.no-team-websites": "هذه المجموعة ليس لديه اي موقع.", - "messages.no-websites-configured": "لم تقم بإعداد اي موقع.", - "messages.team-websites-info": "يمكن مشاهدة الموقع من اي عضو في المجموعة." + "message.visitor-log": "زائر من {country} يستخدم {browser} على {os} {device}" } diff --git a/lang/be-BY.json b/src/lang/be-BY.json similarity index 70% rename from lang/be-BY.json rename to src/lang/be-BY.json index ed8b9be8..32693ebd 100644 --- a/lang/be-BY.json +++ b/src/lang/be-BY.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Дзеянні", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Дадаць сайт", "label.admin": "Адміністратар", + "label.after": "After", "label.all": "Усё", "label.all-time": "Увесь час", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Сярэдняя даўжыня наведвання", "label.back": "Назад", + "label.before": "Before", "label.bounce-rate": "Паказчык адмоваў", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Браўзеры", "label.cancel": "Адмена", "label.change-password": "Змяніць пароль", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Падцвердзіць пароль", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Краіны", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Карыстацкі дыяпазон", "label.dashboard": "Інфармацыйная панэль", "label.data": "Data", + "label.date": "Date", "label.date-range": "Дыяпазон дат", + "label.day": "Day", "label.default-date-range": "Дыяпазон дат па змаўчанню", "label.delete": "Выдаліць", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Выдаліць сайт", + "label.description": "Description", "label.desktop": "Настольны ПК", "label.details": "Details", + "label.device": "Device", "label.devices": "Прылады", "label.dismiss": "Адмена", + "label.does-not-contain": "Does not contain", "label.domain": "Дамен", + "label.dropoff": "Dropoff", "label.edit": "Змяніць", "label.edit-dashboard": "Змяніць інфармацыйную панэль", "label.enable-share-url": "Дазволіць дзяліцца спасылкай", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Падзеі", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Камбініаваны", "label.filter-raw": "Сырыя", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Мова", @@ -52,46 +83,64 @@ "label.last-hours": "Апошнія {x} гадзіны", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Login", "label.logout": "Выйсці", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Мабільны", "label.more": "Болей", + "label.my-websites": "My websites", "label.name": "Імя", "label.new-password": "Новы пароль", "label.none": "Няма", - "label.operating-systems": "Аперацыонныя сістэмы", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Уласнік", + "label.page-of": "Page {current} of {total}", "label.page-views": "Прагляды старонкі", + "label.pageTitle": "Page title", "label.pages": "Старонкі", "label.password": "Пароль", "label.powered-by": "Зроблена {name}", "label.profile": "Профіль", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "У рэяльным часе", + "label.referrer": "Referrer", "label.referrers": "Referrers", "label.refresh": "Аднавіць", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Абавязкова", "label.reset": "Скінуць", "label.reset-website": "Скінуць статыстыку", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Захаваць", "label.screens": "Экраны", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Налады", "label.share-url": "Падзяліцца спасылкай", "label.single-day": "Адзін дзень", + "label.sum": "Sum", "label.tablet": "Планшэт", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Тэма", "label.this-month": "Гэты месяц", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Сёння", "label.toggle-charts": "Пераключыць графікі", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Код адсочвання", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Унікальныя наведвальнікі", "label.unknown": "Невядома", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Імя карыстальніка", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Пабачыць дэталі", + "label.view-only": "View only", "label.views": "Прагляды", "label.visitors": "Наведвальнікі", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Сайты", + "label.window": "Window", "label.yesterday": "Учора", "message.active-users": "{x} тякучых {x, plural, one {наведвальнік} other {наведвальнікаў}}", "message.confirm-delete": "Вы дакладна хочаце выдаліць {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Вы дакладна хочаце скінуць {target} статыстыку?", - "message.delete-website": "Выдаліць сайт", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Усе асацыяваныя дадзеныя будуць таксама выдалены.", "message.error": "Нешта пайшло не так.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Некарэктны username/password.", "message.invalid-domain": "Некарэктны дамен", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Няма дадзеных.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Паролі не супадаюць", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Вы не наладзілі ніводнага сайту.", "message.page-not-found": "Старонка не знойдзена.", - "message.reset-website": "Скінуць статыстыку", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Уся статыстыка для гэтага сайту будзе выдалена, але код адсочвання будзе працягваць працаваць.", "message.saved": "Захавана паспяхова.", "message.share-url": "Гэта публічная спасылка для {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Код адсочвання", "message.user-deleted": "User deleted.", - "message.visitor-log": "Наведвальнік з {country} праз {browser} на {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Вы не наладзілі ніводнага сайту.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Наведвальнік з {country} праз {browser} на {os} {device}" } diff --git a/lang/bn-BD.json b/src/lang/bn-BD.json similarity index 73% rename from lang/bn-BD.json rename to src/lang/bn-BD.json index eca1363b..483d1008 100644 --- a/lang/bn-BD.json +++ b/src/lang/bn-BD.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "অ্যাকশনস", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "ওয়েবসাইট যুক্ত করুন", "label.admin": "অ্যাডমিন", + "label.after": "After", "label.all": "সবগুলো", "label.all-time": "সব সময়", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "গড় পরিদর্শনের সময়", "label.back": "পেছনে", + "label.before": "Before", "label.bounce-rate": "বহিষ্কারের হার", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "ব্রাউজার", "label.cancel": "বাতিল", "label.change-password": "পাসওয়ার্ড পরিবর্তন করুন", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "পাসওয়ার্ড নিশ্চিত করুন", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "দেশ", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "কাস্টম রেঞ্জ", "label.dashboard": "ড্যাশবোর্ড", "label.data": "Data", + "label.date": "Date", "label.date-range": "তারিখের পরিসীমা", + "label.day": "Day", "label.default-date-range": "ডিফল্ট তারিখের পরিসীমা", "label.delete": "মুছে ফেলুন", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "ওয়েবসাইট মুছুন", + "label.description": "Description", "label.desktop": "ডেস্কটপ", "label.details": "Details", + "label.device": "Device", "label.devices": "ডিভাইস গুলো", "label.dismiss": "বাতিল", + "label.does-not-contain": "Does not contain", "label.domain": "ডোমেইন", + "label.dropoff": "Dropoff", "label.edit": "সম্পাদনা করুন", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "শেয়ার ইউআরএল শেয়ার করুন", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "ঘটনা", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "সম্মিলিত", "label.filter-raw": "অপরিশোধিত", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "ভাষা", @@ -52,46 +83,64 @@ "label.last-hours": "শেষ {x} ঘন্টা", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "লগিন", "label.logout": "লগ আউট", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "মুঠোফোন", "label.more": "আরও", + "label.my-websites": "My websites", "label.name": "নাম", "label.new-password": "নতুন পাসওয়ার্ড", "label.none": "কিছুই না", - "label.operating-systems": "অপারেটিং সিস্টেম গুলো", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "মালিক", + "label.page-of": "Page {current} of {total}", "label.page-views": "পৃষ্ঠা পরিদর্শন গুলো", + "label.pageTitle": "Page title", "label.pages": "পৃষ্ঠাগুলি", "label.password": "পাসওয়ার্ড", "label.powered-by": "{name} দ্বারা চালিত", "label.profile": "প্রোফাইল", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "সরাসরি", + "label.referrer": "Referrer", "label.referrers": "রেফারার্স", "label.refresh": "রিফ্রেশ", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "প্রয়োজনীয়", "label.reset": "রিসেট", "label.reset-website": "ওয়েবসাইট রিসেট করুন", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "সংরক্ষণ", "label.screens": "স্ক্রিনগুলি", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "সেটিংস", "label.share-url": "ইউআরএল শেয়ার করুন", "label.single-day": "একদিন", + "label.sum": "Sum", "label.tablet": "ট্যাবলেট", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "থিম", "label.this-month": "এই মাস", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "আজ", "label.toggle-charts": "চার্ট পরিবর্তন করুন", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "ট্র্যাকিং কোড", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "অনন্য ভিজিটর", "label.unknown": "অজানা", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "ব্যবহারকারীর নাম", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "বিস্তারিত দেখুন", + "label.view-only": "View only", "label.views": "ভিউস", "label.visitors": "পরিদর্শনার্থী", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "সবগুলো ওয়েবসাইট", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} বর্তমান {x, plural, one {visitor} other {visitors}}", "message.confirm-delete": "আপনি কি নিশ্চিত যে আপনি {target} মুছতে চান?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "আপনি কি নিশ্চিত যে আপনি {target} এর পরিসংখ্যান পুনরায় সেট করতে চান?", - "message.delete-website": "ওয়েবসাইট মুছুন", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।", "message.error": "কিছু ভুল হয়েছে।", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।", "message.invalid-domain": "ভুল ডোমেন", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "কোন তথ্য নেই।", + "message.no-event-data": "No event data is available.", "message.no-match-password": "পাসওয়ার্ড মেলে না", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "কোনও ওয়েবসাইট কনফিগার করা নেই।", "message.page-not-found": "পৃষ্ঠা খুঁজে পাওয়া যায়নি।", - "message.reset-website": "ওয়েবসাইট রিসেট করুন", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "এই ওয়েবসাইটের সমস্ত পরিসংখ্যান মুছে ফেলা হবে, তবে আপনার ট্র্যাকিং কোডটি অক্ষত থাকবে।", "message.saved": "সংরক্ষিত হয়েছে।", "message.share-url": "এটি {target} এর জন্য প্রকাশ্যে শেয়ার করার ইউআরএল।", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "ট্র্যাকিং কোড", "message.user-deleted": "User deleted.", - "message.visitor-log": "{country} থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন {os} {device} এর মধ্যে।", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "কোনও ওয়েবসাইট কনফিগার করা নেই।", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "{country} থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন {os} {device} এর মধ্যে।" } diff --git a/lang/ca-ES.json b/src/lang/ca-ES.json similarity index 67% rename from lang/ca-ES.json rename to src/lang/ca-ES.json index 3f1d7910..51aee79d 100644 --- a/lang/ca-ES.json +++ b/src/lang/ca-ES.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Accions", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Afegeix lloc web", "label.admin": "Administrador", + "label.after": "After", "label.all": "Tots", "label.all-time": "Sempre", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Temps mitjà de visita", "label.back": "Enrere", + "label.before": "Before", "label.bounce-rate": "Percentatge de rebot", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Navegadors", "label.cancel": "Cancel·la", "label.change-password": "Canvia la contrasenya", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Confirma la contrasenya", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Països", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Rang personalitzat", "label.dashboard": "Panell", "label.data": "Data", + "label.date": "Date", "label.date-range": "Interval de dates", + "label.day": "Day", "label.default-date-range": "Interval de dates per defecte", "label.delete": "Esborra", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Esborra el lloc web", + "label.description": "Description", "label.desktop": "Escriptori", "label.details": "Details", + "label.device": "Device", "label.devices": "Dispositius", "label.dismiss": "Descarta", + "label.does-not-contain": "Does not contain", "label.domain": "Domini", + "label.dropoff": "Dropoff", "label.edit": "Edita", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Activa l'enllaç per compartir", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Esdeveniments", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Combinat", "label.filter-raw": "En cru", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Últimes {x} hores", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Connecta't", "label.logout": "Desconnecta't", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mòbil", "label.more": "Més", + "label.my-websites": "My websites", "label.name": "Nom", "label.new-password": "Contrasenya nova", "label.none": "None", - "label.operating-systems": "Sistemes operatius", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Propietari", + "label.page-of": "Page {current} of {total}", "label.page-views": "Pàgines vistes", + "label.pageTitle": "Page title", "label.pages": "Pàgines", "label.password": "Contrasenya", "label.powered-by": "Funciona amb {name}", "label.profile": "Perfil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Temps real", + "label.referrer": "Referrer", "label.referrers": "Referents", "label.refresh": "Refresca", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Obligatori", "label.reset": "Restableix", "label.reset-website": "Restableix estadístiques", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Desa", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Configuració", "label.share-url": "Enllaç per compartir", "label.single-day": "Un sol dia", + "label.sum": "Sum", "label.tablet": "Tauleta", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Aquest mes", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Avui", "label.toggle-charts": "Mostra/amaga gràfics", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Codi de seguiment", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Visitants únics", "label.unknown": "Desconegut", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Nom d'usuari", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Veure els detalls", + "label.view-only": "View only", "label.views": "Vistes", "label.visitors": "Visitants", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Llocs web", + "label.window": "Window", "label.yesterday": "Ahir", "message.active-users": "{x} {x, plural, one {visitant actual} other {visitants actuals}}", "message.confirm-delete": "Segur que vols esborrar {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Segur que vols restablir les estadístiques de {target}?", - "message.delete-website": "Esborra el lloc web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "També s'esborraran totes les dades relacionades.", "message.error": "S'ha produït un error.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nom d'usuari o contrasenya incorrectes.", "message.invalid-domain": "Domini invàlid", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "No hi ha dades disponibles.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Les contrasenyes no coincideixen", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "No hi ha cap lloc web configurat.", "message.page-not-found": "No s'ha trobat la pàgina.", - "message.reset-website": "Restableix estadístiques", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "S'esborraran totes les estadístiques per aquest lloc web, però el codi de seguiment es mantindrà.", "message.saved": "S'ha desat amb èxit.", "message.share-url": "Aquest és l'enllaç públic per compartir de {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Codi de seguiment", "message.user-deleted": "User deleted.", - "message.visitor-log": "Visitant de {country} usant {browser} a {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "No hi ha cap lloc web configurat.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Visitant de {country} usant {browser} a {os} {device}" } diff --git a/lang/cs-CZ.json b/src/lang/cs-CZ.json similarity index 66% rename from lang/cs-CZ.json rename to src/lang/cs-CZ.json index baf8d5e1..548ee817 100644 --- a/lang/cs-CZ.json +++ b/src/lang/cs-CZ.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Akce", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Přidat web", "label.admin": "Administrátor", + "label.after": "After", "label.all": "Vše", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Průměrný čas návštěvy", "label.back": "Zpět", + "label.before": "Before", "label.bounce-rate": "Okamžité opuštění", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Prohlížeč", "label.cancel": "Zrušit", "label.change-password": "Změnit heslo", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Potvrdit heslo", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Země", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Vlastní rozsah", "label.dashboard": "Přehled", "label.data": "Data", + "label.date": "Date", "label.date-range": "Období", + "label.day": "Day", "label.default-date-range": "Výchozí období", "label.delete": "Smazat", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Smazat web", + "label.description": "Description", "label.desktop": "Stolní počítač", "label.details": "Details", + "label.device": "Device", "label.devices": "Zařízení", "label.dismiss": "Odejít", + "label.does-not-contain": "Does not contain", "label.domain": "Doména", + "label.dropoff": "Dropoff", "label.edit": "Upravit", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Povolit sdílení URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Události", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Kombinace", "label.filter-raw": "Nezpracované", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Posledních {x} hodin", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Přihlásit", "label.logout": "Odhlásit", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobilní telefon", "label.more": "Více", + "label.my-websites": "My websites", "label.name": "Jméno", "label.new-password": "Nové heslo", "label.none": "None", - "label.operating-systems": "Operační systém", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Zobrazení stránek", + "label.pageTitle": "Page title", "label.pages": "Stránky", "label.password": "Heslo", "label.powered-by": "Běží na {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Aktuálně", + "label.referrer": "Referrer", "label.referrers": "Odkazy", "label.refresh": "Obnovit", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Vyžadováno", "label.reset": "Reset", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Uložit", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Nastavení", "label.share-url": "Sdílet URL", "label.single-day": "Jeden den", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Tento měsíc", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Dnes", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Sledovací kód", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Jedinečné návštěvy", "label.unknown": "Neznámý", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Uživatelské jméno", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Zobrazit detaily", + "label.view-only": "View only", "label.views": "Zobrazení", "label.visitors": "Návštěvy", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Weby", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} aktuálně {x, plural, one {návštěvník} other {návštěvníci}}", "message.confirm-delete": "Opravdu smazat {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Smazat web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Všechna související data budou také smazána.", "message.error": "Něco se pokazilo.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nesprávné jméno/heslo.", "message.invalid-domain": "Neplatná doména", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Žádná data.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Hesla se neschodují", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Nemáte nastavený žádný web.", "message.page-not-found": "Stránka nenalezena.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Úspěšně uloženo.", "message.share-url": "Toto je sdílené URL pro {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Sledovací kód", "message.user-deleted": "User deleted.", - "message.visitor-log": "Návštěvník z {country} s prohlížečem {browser} na {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Nemáte nastavený žádný web.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Návštěvník z {country} s prohlížečem {browser} na {os} {device}" } diff --git a/lang/da-DK.json b/src/lang/da-DK.json similarity index 66% rename from lang/da-DK.json rename to src/lang/da-DK.json index d8c94f84..9d4fe50e 100644 --- a/lang/da-DK.json +++ b/src/lang/da-DK.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Handlinger", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Tilføj hjemmeside", "label.admin": "Administrator", + "label.after": "After", "label.all": "Alle", "label.all-time": "Altid", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Gennemsnitlig besøgstid", "label.back": "Tilbage", + "label.before": "Before", "label.bounce-rate": "Afvisningsprocent", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Browsere", "label.cancel": "Afvis", "label.change-password": "Skift adgangskode", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Godkendt adgangskode", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Lande", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Tilpasset interval", "label.dashboard": "Betjeningspanel", "label.data": "Data", + "label.date": "Date", "label.date-range": "Datointerval", + "label.day": "Day", "label.default-date-range": "Standard datointerval", "label.delete": "Slet", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Slet hjemmeside", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Enheder", "label.dismiss": "Afvis", + "label.does-not-contain": "Does not contain", "label.domain": "Domæne", + "label.dropoff": "Dropoff", "label.edit": "Rediger", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Aktivér delings-URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Hændelser", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Kombineret", "label.filter-raw": "Rå", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Sprog", @@ -52,46 +83,64 @@ "label.last-hours": "Sidste {x} timer", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Log ind", "label.logout": "Log ud", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobil", "label.more": "Mere", + "label.my-websites": "My websites", "label.name": "Navn", "label.new-password": "Ny adgangskode", "label.none": "None", - "label.operating-systems": "Operativsystemer", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Ejer", + "label.page-of": "Page {current} of {total}", "label.page-views": "Sidevisninger", + "label.pageTitle": "Page title", "label.pages": "Sider", "label.password": "Adgangskode", "label.powered-by": "Drevet af {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Realtid", + "label.referrer": "Referrer", "label.referrers": "Henvisninger", "label.refresh": "Opdater", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Påkrævet", "label.reset": "Nulstil", "label.reset-website": "Nulstil statistikker", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Gem", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Indstillinger", "label.share-url": "Del URL", "label.single-day": "Enkelt dag", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Tema", "label.this-month": "Denne måned", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Idag", "label.toggle-charts": "Ændre graf", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Sporingskode", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Unikke besøgende", "label.unknown": "Ukendt", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Brugernavn", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Vis detajler", + "label.view-only": "View only", "label.views": "Visninger", "label.visitors": "Besøgende", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Hjemmesider", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} nuværende {x, plural, one {bruger} other {brugere}}", "message.confirm-delete": "Er du sikker på at du vil slette {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Er du sikker på at du ville nulstille {target}'s statistikker?", - "message.delete-website": "Slet hjemmeside", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Alle tilknyttede data slettes også.", "message.error": "Noget gik galt.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Ugyldigt brugernavn/adgangskode.", "message.invalid-domain": "Ugyldigt domæne", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Ingen data tilgængelig.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Adgangskoderne matcher ikke", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Du har ikke konfigureret nogen hjemmesider.", "message.page-not-found": "Side ikke fundet.", - "message.reset-website": "Nulstil statistikker", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Alle statistikker for denne hjemmeside ville blive slettet, men sporingskode ville forblive intakt.", "message.saved": "Gemt!", "message.share-url": "Dette er den offentlige delings-URL til {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Sporingskode", "message.user-deleted": "User deleted.", - "message.visitor-log": "Besøgende fra {country} bruger {browser} på {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Du har ikke konfigureret nogen hjemmesider.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Besøgende fra {country} bruger {browser} på {os} {device}" } diff --git a/src/lang/de-CH.json b/src/lang/de-CH.json new file mode 100644 index 00000000..5c6c45d1 --- /dev/null +++ b/src/lang/de-CH.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Zuegangscode", + "label.actions": "Aktione", + "label.activity-log": "Aktivitätsverlauf", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "Websiite hinzuefüege", + "label.admin": "Administrator", + "label.after": "After", + "label.all": "Alli", + "label.all-time": "Gesamte Zitruum", + "label.analytics": "Analytics", + "label.average": "Average", + "label.average-visit-time": "Durchschn. Bsuechsziit", + "label.back": "Zrugg", + "label.before": "Before", + "label.bounce-rate": "Absprungsrate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Browser", + "label.cancel": "Abbreche", + "label.change-password": "Passwort ändere", + "label.cities": "Städt", + "label.city": "City", + "label.clear-all": "Alles lösche", + "label.confirm": "Bestätige", + "label.confirm-password": "Passwort widerhole", + "label.contains": "Contains", + "label.continue": "Wiiter", + "label.countries": "Länder", + "label.country": "Country", + "label.create-report": "Create report", + "label.create-team": "Team erstelle", + "label.create-user": "Benutzer erstelle", + "label.created": "Erstellt", + "label.current-password": "Jetzigs Passwort", + "label.custom-range": "Benutzerdefinierte Bereich", + "label.dashboard": "Übersicht", + "label.data": "Datä", + "label.date": "Date", + "label.date-range": "Datumsbereich", + "label.day": "Day", + "label.default-date-range": "Vorigstellte Datumsbereich", + "label.delete": "Lösche", + "label.delete-team": "Team lösche", + "label.delete-user": "Benutzer lösche", + "label.delete-website": "Websiite lösche", + "label.description": "Description", + "label.desktop": "Desktop", + "label.details": "Details", + "label.device": "Device", + "label.devices": "Grät", + "label.dismiss": "Verwerfe", + "label.does-not-contain": "Does not contain", + "label.domain": "Domain", + "label.dropoff": "Dropoff", + "label.edit": "Bearbeite", + "label.edit-dashboard": "Dashboard bearbeite", + "label.enable-share-url": "Freigab-URL aktiviere", + "label.event": "Event", + "label.event-data": "Event data", + "label.events": "Ereigniss", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", + "label.filter-combined": "Kombiniert", + "label.filter-raw": "Rohdate", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Biträte", + "label.join-team": "Team biträte", + "label.language": "Sprach", + "label.languages": "Sprache", + "label.laptop": "Laptop", + "label.last-days": "Letzti {x} Täg", + "label.last-hours": "Letzti {x} Stunde", + "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.max": "Max", + "label.members": "Mitglieder", + "label.min": "Min", + "label.mobile": "Handy", + "label.more": "Meh", + "label.my-websites": "My websites", + "label.name": "Name", + "label.new-password": "Neus Passwort", + "label.none": "Keis", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "Bsitzer", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Siitenufrüef", + "label.pageTitle": "Page title", + "label.pages": "Siite", + "label.password": "Passwort", + "label.powered-by": "Betribe dur {name}", + "label.profile": "Profil", + "label.queries": "Abfrage", + "label.query": "Query", + "label.query-parameters": "Abfragparameter", + "label.realtime": "Echtzit", + "label.referrer": "Referrer", + "label.referrers": "Referrer", + "label.refresh": "Aktualisiere", + "label.regenerate": "Erneuere", + "label.region": "Region", + "label.regions": "Regionä", + "label.remove": "Entferne", + "label.reports": "Reports", + "label.required": "Erforderlich", + "label.reset": "Zruggsetze", + "label.reset-website": "Statistik zruggsetze", + "label.retention": "Retention", + "label.role": "Rollä", + "label.run-query": "Run query", + "label.save": "Speichere", + "label.screens": "Bildschirmuflösige", + "label.select-date": "Select date", + "label.select-website": "Websiite uuswähle", + "label.sessions": "Sessions", + "label.settings": "Istellige", + "label.share-url": "Freigab-URL", + "label.single-day": "Ein Tag", + "label.sum": "Sum", + "label.tablet": "Tablet", + "label.team": "Team", + "label.team-guest": "Team Gast", + "label.team-id": "Team ID", + "label.team-member": "Team Mitglied", + "label.team-name": "Team name", + "label.team-owner": "Team Bsitzer", + "label.team-websites": "Team websites", + "label.teams": "Teams", + "label.theme": "Thema", + "label.this-month": "De Monet", + "label.this-week": "Die Wuche", + "label.this-year": "Das Jahr", + "label.timezone": "Ziitzone", + "label.title": "Titel", + "label.today": "Hüt", + "label.toggle-charts": "Schaubilder umschalte", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Tracking Code", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", + "label.unique-visitors": "Eidütigi Bsuecher", + "label.unknown": "Unbekannt", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "Benutzer", + "label.username": "Benutzername", + "label.users": "Benutzer", + "label.value": "Value", + "label.view": "Azeige", + "label.view-details": "Details azeige", + "label.view-only": "View only", + "label.views": "Ufrüef", + "label.visitors": "Bsuecher", + "label.website": "Website", + "label.website-id": "Websiite ID", + "label.websites": "Websiite", + "label.window": "Window", + "label.yesterday": "Gester", + "message.active-users": "{x} {x, plural, one {aktive Bsuecher} other {aktivi Bsuecher}}", + "message.confirm-delete": "Sind Sie sich sicher, {target} zlösche?", + "message.confirm-leave": "Sind Sie sich sicher, {target} zverlah?", + "message.confirm-reset": "Sind Sie sicher, dass Sie dStatistike vo {target} zruggsetze wend?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", + "message.delete-website-warning": "Alli dezueghörige Date werdet ebefalls glöscht.", + "message.error": "Es isch en Fehler uftrete.", + "message.event-log": "{event} uf {url}", + "message.go-to-settings": "Zu de Istellige", + "message.incorrect-username-password": "Falschs 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.no-data-available": "Kei Date vorhande.", + "message.no-event-data": "No event data is available.", + "message.no-match-password": "Passwörter stimmed ned überi", + "message.no-results-found": "No results were found.", + "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-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-not-found": "Team nöd gfunde.", + "message.team-websites-info": "Websiite chönd vo jedem im Team agluegt werde", + "message.tracking-code": "Tracking Code", + "message.user-deleted": "Benutzer glöscht.", + "message.visitor-log": "Bsuecher us {country} benutzt {browser} uf {os} {device}" +} diff --git a/lang/de-DE.json b/src/lang/de-DE.json similarity index 58% rename from lang/de-DE.json rename to src/lang/de-DE.json index 0190d13c..3307dfa4 100644 --- a/lang/de-DE.json +++ b/src/lang/de-DE.json @@ -2,96 +2,145 @@ "label.access-code": "Zugangscode", "label.actions": "Aktionen", "label.activity-log": "Aktivitätsverlauf", + "label.add": "Add", + "label.add-description": "Beschreibung hinzufügen", "label.add-website": "Webseite hinzufügen", "label.admin": "Administrator", + "label.after": "After", "label.all": "Alle", "label.all-time": "Gesamter Zeitraum", "label.analytics": "Analytics", + "label.average": "Durchschnitt", "label.average-visit-time": "Durchschn. Besuchszeit", "label.back": "Zurück", + "label.before": "Before", "label.bounce-rate": "Absprungrate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Browser", "label.cancel": "Abbrechen", "label.change-password": "Passwort ändern", "label.cities": "Städte", + "label.city": "City", "label.clear-all": "Alles löschen", "label.confirm": "Bestätigen", "label.confirm-password": "Passwort wiederholen", + "label.contains": "Contains", "label.continue": "Weiter", "label.countries": "Länder", - "label.create-team": "Erstelle Team", - "label.create-user": "Erstelle Nutzer", + "label.country": "Country", + "label.create-report": "Report erstellen", + "label.create-team": "Team erstellen", + "label.create-user": "Benutzer erstellen", "label.created": "Erstellt", "label.current-password": "Derzeitiges Passwort", "label.custom-range": "Benutzerdefinierter Bereich", "label.dashboard": "Übersicht", "label.data": "Daten", + "label.date": "Date", "label.date-range": "Datumsbereich", + "label.day": "Day", "label.default-date-range": "Voreingestellter Datumsbereich", "label.delete": "Löschen", - "label.delete-team": "Lösche Team", - "label.delete-user": "Lösche Nutzer", + "label.delete-team": "Team löschen", + "label.delete-user": "Benutzer löschen", "label.delete-website": "Webseite löschen", + "label.description": "Beschreibung", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Geräte", "label.dismiss": "Verwerfen", + "label.does-not-contain": "Does not contain", "label.domain": "Domain", + "label.dropoff": "Dropoff", "label.edit": "Bearbeiten", "label.edit-dashboard": "Dashboard bearbeiten", "label.enable-share-url": "Freigabe-URL aktivieren", + "label.event": "Event", + "label.event-data": "Event daten", "label.events": "Ereignisse", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Kombiniert", "label.filter-raw": "Rohdaten", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Größer als", + "label.greater-than-equals": "Größer oder gleich", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Beitreten", "label.join-team": "Team beitreten", "label.language": "Sprache", "label.languages": "Sprachen", "label.laptop": "Laptop", - "label.last-days": "Letzten {x} Tage", - "label.last-hours": "Letzten {x} Stunden", + "label.last-days": "Letzte {x} Tage", + "label.last-hours": "Letzte {x} Stunden", "label.leave": "Verlassen", "label.leave-team": "Team verlassen", + "label.less-than": "Kleiner als", + "label.less-than-equals": "Kleiner oder gleich", "label.login": "Anmelden", "label.logout": "Abmelden", + "label.max": "Max", "label.members": "Mitglieder", + "label.min": "Min", "label.mobile": "Handy", "label.more": "Mehr", + "label.my-websites": "My websites", "label.name": "Name", "label.new-password": "Neues Passwort", "label.none": "Keine", - "label.operating-systems": "Betriebssysteme", + "label.os": "OS", + "label.overview": "Übersicht", "label.owner": "Besitzer", + "label.page-of": "Page {current} of {total}", "label.page-views": "Seitenaufrufe", + "label.pageTitle": "Page title", "label.pages": "Seiten", "label.password": "Passwort", "label.powered-by": "Betrieben durch {name}", "label.profile": "Profil", "label.queries": "Abfragen", + "label.query": "Abfrage", "label.query-parameters": "Abfrageparameter", "label.realtime": "Echtzeit", + "label.referrer": "Referrer", "label.referrers": "Referrer", "label.refresh": "Aktualisieren", "label.regenerate": "Erneuern", - "label.regions": "Regions", + "label.region": "Region", + "label.regions": "Regionen", "label.remove": "Entfernen", + "label.reports": "Reporte", "label.required": "Erforderlich", "label.reset": "Zurücksetzen", "label.reset-website": "Statistik zurücksetzen", + "label.retention": "Retention", "label.role": "Rolle", + "label.run-query": "Abfrage starten", "label.save": "Speichern", "label.screens": "Bildschirmauflösungen", + "label.select-date": "Datum auswählen", "label.select-website": "Website auswählen", "label.sessions": "Sessions", "label.settings": "Einstellungen", "label.share-url": "Freigabe-URL", "label.single-day": "Ein Tag", + "label.sum": "Summe", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team Gast", "label.team-id": "Team ID", "label.team-member": "Team Mitglied", + "label.team-name": "Team name", "label.team-owner": "Team Eigentümer", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Thema", "label.this-month": "Diesen Monat", @@ -101,46 +150,62 @@ "label.title": "Titel", "label.today": "Heute", "label.toggle-charts": "Schaubilder umschalten", - "label.tracking-code": "Tracking Kennung", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Tracking Code", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Eindeutige Besucher", "label.unknown": "Unbekannt", - "label.user": "User", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "Benutzer", "label.username": "Benutzername", - "label.users": "Users", - "label.view": "View", + "label.users": "Benutzer", + "label.value": "Value", + "label.view": "Anzeigen", "label.view-details": "Details anzeigen", + "label.view-only": "View only", "label.views": "Aufrufe", "label.visitors": "Besucher", - "label.website-id": "Website ID", + "label.website": "Webseite", + "label.website-id": "Webseite ID", "label.websites": "Webseiten", + "label.window": "Window", "label.yesterday": "Gestern", "message.active-users": "{x} {x, plural, one {aktiver Besucher} other {aktive Besucher}}", "message.confirm-delete": "Sind Sie sich sicher, {target} zu löschen?", "message.confirm-leave": "Sind Sie sicher, dass die {target} verlassen möchten?", "message.confirm-reset": "Sind Sie sicher, dass Sie die Statistiken von {target} zurücksetzen wollen?", - "message.delete-website": "Webseite löschen", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.", "message.error": "Es ist ein Fehler aufgetreten.", - "message.event-log": "{event} on {url}", + "message.event-log": "{event} auf {url}", "message.go-to-settings": "Zu den Einstellungen", "message.incorrect-username-password": "Falsches Passwort oder Benutzername.", "message.invalid-domain": "Ungültige Domain", "message.min-password-length": "Minimale länge von {n} Zeichen", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Keine Daten vorhanden.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Passwörter stimmen nicht überein", + "message.no-results-found": "Keine Ergebnisse gefunden.", + "message.no-team-websites": "Diesem Team sind keine Websites zugeordnet.", "message.no-teams": "Bisher wurden keine Teams erstellt.", - "message.no-users": "Hier gibt es keine Nutzer.", + "message.no-users": "Hier gibt es keine Benutzer.", + "message.no-websites-configured": "Es ist keine Webseite vorhanden.", "message.page-not-found": "Seite nicht gefunden.", - "message.reset-website": "Statistik zurücksetzen", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Alle Daten für diese Webseite werden gelöscht, jedoch bleibt der Tracking Code bestehen.", "message.saved": "Erfolgreich gespeichert.", - "message.share-url": "Dies ist die öffentliche URL zum Teilen für {target}.", + "message.share-url": "Ihre Webseitenstatistik ist unter der folgenden URL öffentlich zugänglich:", "message.team-already-member": "Sie sind bereits Mitglied des Teams.", "message.team-not-found": "Team nicht gefunden.", - "message.tracking-code": "Tracking Kennung", - "message.user-deleted": "Nutzer gelöscht.", - "message.visitor-log": "Besucher aus {country} benutzt {browser} auf {os} {device}", - "messages.no-team-websites": "Diesem Team sind keine Websites zugeordnet.", - "messages.no-websites-configured": "Es ist keine Webseite vorhanden.", - "messages.team-websites-info": "Webseiten können von jedem im Team eingesehen werden." + "message.team-websites-info": "Webseiten können von jedem im Team eingesehen werden.", + "message.tracking-code": "Tracking Code", + "message.user-deleted": "Benutzer gelöscht.", + "message.visitor-log": "Besucher aus {country} benutzt {browser} auf {os} {device}" } diff --git a/lang/el-GR.json b/src/lang/el-GR.json similarity index 71% rename from lang/el-GR.json rename to src/lang/el-GR.json index f32cd93a..dd95c777 100644 --- a/lang/el-GR.json +++ b/src/lang/el-GR.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Ενέργειες", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Προσθήκη ιστότοπου", "label.admin": "Διαχειριστής", + "label.after": "After", "label.all": "All", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Μέσος χρόνος επίσκεψης", "label.back": "Πίσω", + "label.before": "Before", "label.bounce-rate": "Ποσοστό αναπήδησης", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Προγράμματα περιήγησης", "label.cancel": "Ακύρωση", "label.change-password": "Αλλαγή κωδικού", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Επιβεβαίωση κωδικού", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Χώρες", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Προσαρμοσμένο εύρος", "label.dashboard": "Πίνακας", "label.data": "Data", + "label.date": "Date", "label.date-range": "Εύρος ημερομηνιών", + "label.day": "Day", "label.default-date-range": "Προεπιλεγμένο εύρος ημερομηνιών", "label.delete": "Διαγραφή", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Διαγραφή ιστότοπου", + "label.description": "Description", "label.desktop": "Σταθερός υπολογιστής", "label.details": "Details", + "label.device": "Device", "label.devices": "Συσκευές", "label.dismiss": "Dismiss", + "label.does-not-contain": "Does not contain", "label.domain": "Τομέας", + "label.dropoff": "Dropoff", "label.edit": "Επεξεργασία", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Ενεργοποίηση κοινής χρήσης URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Γεγονότα", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Σε συνδυασμό", "label.filter-raw": "Ακατέργαστο", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Τελευταίες {x} ώρες", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Είσοδος", "label.logout": "Αποσύνδεση", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Κινητό", "label.more": "Περισσότερα", + "label.my-websites": "My websites", "label.name": "Όνομα", "label.new-password": "Νέος κωδικός", "label.none": "None", - "label.operating-systems": "Λειτουργικά συστήματα", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Προβολές σελίδας", + "label.pageTitle": "Page title", "label.pages": "Σελίδες", "label.password": "Κωδικός", "label.powered-by": "Με την υποστήριξη του {name}", "label.profile": "Προφίλ", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Realtime", + "label.referrer": "Referrer", "label.referrers": "Παραπομπές", "label.refresh": "Ανανέωση", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Απαιτείται", "label.reset": "Επαναφορά", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Αποθήκευση", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Ρυθμίσεις", "label.share-url": "Κοινοποίηση διεύθυνσης URL", "label.single-day": "Ημερήσια", + "label.sum": "Sum", "label.tablet": "Τάμπλετ", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Αυτο το μήνα", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Σήμερα", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Κωδικός παρακολούθησης", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Μοναδικοί επισκέπτες", "label.unknown": "Άγνωστο", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Όνομα χρήστη", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Λεπτομέρειες", + "label.view-only": "View only", "label.views": "Προβολές", "label.visitors": "Επισκέπτες", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Ιστότοποι", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} ενεργοί {x, plural, one {επισκέπτης} other {επισκέπτες}}", "message.confirm-delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε το {target};", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Διαγραφή ιστότοπου", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης.", "message.error": "Κάτι πήγε στραβά.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Εσφαλμένο όνομα χρήστη / κωδικός πρόσβασης.", "message.invalid-domain": "Μη έγκυρος τομέας", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Δεν υπάρχουν διαθέσιμα δεδομένα.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Οι κωδικοί πρόσβασης δεν ταιριάζουν", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Δεν έχετε ρυθμίσει κανένα ιστότοπο.", "message.page-not-found": "Η σελίδα δεν βρέθηκε.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Αποθηκεύτηκε επιτυχώς.", "message.share-url": "Αυτό είναι το κοινόχρηστο URL για το {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Κωδικός παρακολούθησης", "message.user-deleted": "User deleted.", - "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Δεν έχετε ρυθμίσει κανένα ιστότοπο.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}" } diff --git a/lang/en-GB.json b/src/lang/en-GB.json similarity index 66% rename from lang/en-GB.json rename to src/lang/en-GB.json index 296106f2..4efaec5d 100644 --- a/lang/en-GB.json +++ b/src/lang/en-GB.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Actions", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Add website", "label.admin": "Administrator", + "label.after": "After", "label.all": "All", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Average visit time", "label.back": "Back", + "label.before": "Before", "label.bounce-rate": "Bounce rate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Browsers", "label.cancel": "Cancel", "label.change-password": "Change password", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Confirm password", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Countries", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Custom range", "label.dashboard": "Dashboard", "label.data": "Data", + "label.date": "Date", "label.date-range": "Date range", + "label.day": "Day", "label.default-date-range": "Default date range", "label.delete": "Delete", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Delete website", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Devices", "label.dismiss": "Dismiss", + "label.does-not-contain": "Does not contain", "label.domain": "Domain", + "label.dropoff": "Dropoff", "label.edit": "Edit", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Enable share URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Events", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Combined", "label.filter-raw": "Raw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Last {x} hours", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Login", "label.logout": "Logout", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobile", "label.more": "More", + "label.my-websites": "My websites", "label.name": "Name", "label.new-password": "New password", "label.none": "None", - "label.operating-systems": "Operating systems", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Page views", + "label.pageTitle": "Page title", "label.pages": "Pages", "label.password": "Password", "label.powered-by": "Powered by {name}", "label.profile": "Profile", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Realtime", + "label.referrer": "Referrer", "label.referrers": "Referrers", "label.refresh": "Refresh", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Required", "label.reset": "Reset", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Save", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Settings", "label.share-url": "Share URL", "label.single-day": "Single day", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "This month", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Today", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Tracking code", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Unique visitors", "label.unknown": "Unknown", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Username", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "View details", + "label.view-only": "View only", "label.views": "Views", "label.visitors": "Visitors", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Websites", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} current {x, plural, one {visitor} other {visitors}}", "message.confirm-delete": "Are you sure you want to delete {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are you sure you want to reset {target}'s statistics?", - "message.delete-website": "Delete website", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "All associated data will be deleted as well.", "message.error": "Something went wrong.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Incorrect username/password.", "message.invalid-domain": "Invalid domain", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "No data available.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Passwords don't match", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "You don't have any websites configured.", "message.page-not-found": "Page not found.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Saved successfully.", "message.share-url": "This is the publicly shared URL for {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Tracking code", "message.user-deleted": "User deleted.", - "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "You don't have any websites configured.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}" } diff --git a/lang/en-US.json b/src/lang/en-US.json similarity index 68% rename from lang/en-US.json rename to src/lang/en-US.json index e80398c6..b7c77a69 100644 --- a/lang/en-US.json +++ b/src/lang/en-US.json @@ -2,47 +2,78 @@ "label.access-code": "Access code", "label.actions": "Actions", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Add website", "label.admin": "Administrator", + "label.after": "After", "label.all": "All", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Average visit time", "label.back": "Back", + "label.before": "Before", "label.bounce-rate": "Bounce rate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Browsers", "label.cancel": "Cancel", "label.change-password": "Change password", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Confirm password", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Countries", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", "label.current-password": "Current password", - "label.custom-range": "Custom-range", + "label.custom-range": "Custom range", "label.dashboard": "Dashboard", "label.data": "Data", + "label.date": "Date", "label.date-range": "Date range", + "label.day": "Day", "label.default-date-range": "Default date range", "label.delete": "Delete", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Delete website", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Devices", "label.dismiss": "Dismiss", + "label.does-not-contain": "Does not contain", "label.domain": "Domain", + "label.dropoff": "Dropoff", "label.edit": "Edit", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Enable share URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Events", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Combined", "label.filter-raw": "Raw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Last {x} hours", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Login", "label.logout": "Logout", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobile", "label.more": "More", + "label.my-websites": "My websites", "label.name": "Name", "label.new-password": "New password", "label.none": "None", - "label.operating-systems": "Operating systems", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Page views", + "label.pageTitle": "Page title", "label.pages": "Pages", "label.password": "Password", "label.powered-by": "Powered by {name}", "label.profile": "Profile", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Realtime", + "label.referrer": "Referrer", "label.referrers": "Referrers", "label.refresh": "Refresh", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Required", "label.reset": "Reset", "label.reset-website": "Reset website", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Save", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Settings", "label.share-url": "Share URL", "label.single-day": "Single day", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "This month", @@ -101,23 +150,36 @@ "label.title": "Title", "label.today": "Today", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Tracking code", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Unique visitors", "label.unknown": "Unknown", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Username", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "View details", + "label.view-only": "View only", "label.views": "Views", "label.visitors": "Visitors", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Websites", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} current {x, plural, one {visitor} other {visitors}}", "message.confirm-delete": "Are you sure you want to delete {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are you sure you want to reset {target}?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "All website data will be deleted.", "message.error": "Something went wrong.", @@ -126,10 +188,15 @@ "message.incorrect-username-password": "Incorrect username and/or password.", "message.invalid-domain": "Invalid domain. Do not include http/https.", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "No data available.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Passwords do not match.", + "message.no-results-found": "No results found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "You do not have any websites configured.", "message.page-not-found": "Page not found", "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your settings will remain intact.", @@ -137,10 +204,8 @@ "message.share-url": "Your website stats are publically available at the following URL:", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "To track stats for this website, place the following code in the ... section of your HTML.", "message.user-deleted": "User deleted.", - "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "You do not have any websites configured.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}" } diff --git a/src/lang/es-ES.json b/src/lang/es-ES.json new file mode 100644 index 00000000..7a401e51 --- /dev/null +++ b/src/lang/es-ES.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Código de acceso", + "label.actions": "Acciones", + "label.activity-log": "Registro de actividad", + "label.add": "Añadir", + "label.add-description": "Añadir descripción", + "label.add-website": "Nuevo sitio web", + "label.admin": "Administrador", + "label.after": "Después", + "label.all": "Todos", + "label.all-time": "Todos los tiempos", + "label.analytics": "Analíticas", + "label.average": "Media", + "label.average-visit-time": "Tiempo promedio de visita", + "label.back": "Atrás", + "label.before": "Antes", + "label.bounce-rate": "Porcentaje de rebote", + "label.breakdown": "Desglose", + "label.browser": "Browser", + "label.browsers": "Navegadores", + "label.cancel": "Cancelar", + "label.change-password": "Cambiar contraseña", + "label.cities": "Ciudades", + "label.city": "City", + "label.clear-all": "Limpiar todo", + "label.confirm": "Confirmar", + "label.confirm-password": "Confirmar contraseña", + "label.contains": "Contiene", + "label.continue": "Continuar", + "label.countries": "Países", + "label.country": "Country", + "label.create-report": "Crear reporte", + "label.create-team": "Crear equipo", + "label.create-user": "Crear usuario", + "label.created": "Creado", + "label.current-password": "Contraseña actual", + "label.custom-range": "Intervalo personalizado", + "label.dashboard": "Panel de control", + "label.data": "Datos", + "label.date": "Date", + "label.date-range": "Intervalo de fechas", + "label.day": "Day", + "label.default-date-range": "Intervalo por defecto", + "label.delete": "Eliminar", + "label.delete-team": "Eliminar equipo", + "label.delete-user": "Eliminar usuario", + "label.delete-website": "Eliminar sitio", + "label.description": "Descripciones", + "label.desktop": "Escritorio", + "label.details": "Detalles", + "label.device": "Device", + "label.devices": "Dispositivos", + "label.dismiss": "Ignorar", + "label.does-not-contain": "No contiene", + "label.domain": "Dominio", + "label.dropoff": "Dropoff", + "label.edit": "Editar", + "label.edit-dashboard": "Editar panel", + "label.enable-share-url": "Habilitar compartir URL", + "label.event": "Evento", + "label.event-data": "Datos de evento", + "label.events": "Eventos", + "label.false": "False", + "label.field": "Campo", + "label.fields": "Campos", + "label.filter-combined": "Combinado", + "label.filter-raw": "En crudo", + "label.filters": "Filtros", + "label.funnel": "Funnel", + "label.greater-than": "Mayor que", + "label.greater-than-equals": "Mayor que o igual a", + "label.insights": "Insights", + "label.is": "Es igual a", + "label.is-not": "No es igual a", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Unir", + "label.join-team": "Unirse al equipo", + "label.language": "Idioma", + "label.languages": "Idiomas", + "label.laptop": "Portátil", + "label.last-days": "Últimos {x} días", + "label.last-hours": "Últimas {x} horas", + "label.leave": "Abandonar", + "label.leave-team": "Abandonar equipo", + "label.less-than": "Menor que", + "label.less-than-equals": "Menor que o igual a", + "label.login": "Iniciar sesión", + "label.logout": "Cerrar sesión", + "label.max": "Máx", + "label.members": "Miembros", + "label.min": "Mín", + "label.mobile": "Móvil", + "label.more": "Más", + "label.my-websites": "My websites", + "label.name": "Nombre", + "label.new-password": "Nueva contraseña", + "label.none": "Ninguno", + "label.os": "OS", + "label.overview": "Resumen", + "label.owner": "Propietario", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Vistas", + "label.pageTitle": "Page title", + "label.pages": "Páginas", + "label.password": "Contraseña", + "label.powered-by": "Con la ayuda de {name}", + "label.profile": "Perfil", + "label.queries": "Consultas", + "label.query": "Query", + "label.query-parameters": "Parámetros de petición", + "label.realtime": "Tiempo real", + "label.referrer": "Referrer", + "label.referrers": "Referido desde", + "label.refresh": "Actualizar", + "label.regenerate": "Regenerar", + "label.region": "Region", + "label.regions": "Regiones", + "label.remove": "Quitar", + "label.reports": "Reportes", + "label.required": "Obligatorio", + "label.reset": "Reiniciar", + "label.reset-website": "Reiniciar estadísticas", + "label.retention": "Retention", + "label.role": "Rol", + "label.run-query": "Ejecutar consulta", + "label.save": "Guardar", + "label.screens": "Pantallas", + "label.select-date": "Seleccionar fecha", + "label.select-website": "Seleccionar sitio web", + "label.sessions": "Sesiones", + "label.settings": "Configuraciones", + "label.share-url": "Compartir URL", + "label.single-day": "Un solo día", + "label.sum": "Suma", + "label.tablet": "Tableta", + "label.team": "Equipo", + "label.team-guest": "Invitado al equipo", + "label.team-id": "ID de equipo", + "label.team-member": "Miembro del equipo", + "label.team-name": "Team name", + "label.team-owner": "Admin. del equipo", + "label.team-websites": "Team websites", + "label.teams": "Equipos", + "label.theme": "Tema", + "label.this-month": "Este mes", + "label.this-week": "Esta semana", + "label.this-year": "Este año", + "label.timezone": "Zona horaria", + "label.title": "Título", + "label.today": "Hoy", + "label.toggle-charts": "Alternar gráficas", + "label.total": "Total", + "label.total-records": "Total de registros", + "label.tracking-code": "Código de rastreo", + "label.true": "Verdadero", + "label.type": "Tipo", + "label.unique": "Único", + "label.unique-visitors": "Visitantes únicos", + "label.unknown": "Desconocida", + "label.untitled": "Sin título", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "Usuario", + "label.username": "Nombre de usuario", + "label.users": "Usuarios", + "label.value": "Valor", + "label.view": "Visualizar", + "label.view-details": "Ver detalles", + "label.view-only": "Ver sólo", + "label.views": "Vistas", + "label.visitors": "Visitantes", + "label.website": "Sitio web", + "label.website-id": "ID del sitio web", + "label.websites": "Sitios web", + "label.window": "Ventana", + "label.yesterday": "Ayer", + "message.active-users": "{x} {x, plural, one {activo} other {activos}}", + "message.confirm-delete": "¿Seguro que quieres eliminar {target}?", + "message.confirm-leave": "¿Seguro que quieres abandonar {target}?", + "message.confirm-reset": "¿Seguro que quieres BORRAR las analíticas de {target}?", + "message.delete-account": "Para borrar esta cuenta, escribe {confirmation} a continuación para confirmar.", + "message.delete-website": "Para borrar este sitio web, escribe {confirmation} a continuación para confirmar.", + "message.delete-website-warning": "Toda la información relacionada será eliminada.", + "message.error": "Algo falló.", + "message.event-log": "{event} en {url}", + "message.go-to-settings": "Ir a la configuración", + "message.incorrect-username-password": "Nombre de usuario o contraseña incorrectos.", + "message.invalid-domain": "Dominio inválido", + "message.min-password-length": "Longitud mínima de {n} caracteres", + "message.new-version-available": "A new version of Umami {version} is available!", + "message.no-data-available": "No hay información disponible.", + "message.no-event-data": "No hay datos de eventos disponibles.", + "message.no-match-password": "Las contraseñas no coinciden", + "message.no-results-found": "No se encontraron resultados.", + "message.no-team-websites": "Este equipo no tiene ningún sitio web configurado.", + "message.no-teams": "No has creado ningún equipo.", + "message.no-users": "No hay usuarios.", + "message.no-websites-configured": "No tienes ningún sitio web configurado.", + "message.page-not-found": "Página no encontrada", + "message.reset-website": "Para reiniciar este sitio web, escribe {confirmation} a continuación para confirmar.", + "message.reset-website-warning": "Todas las estadísticas de esta página serán eliminadas, pero el código de rastreo permanecerá intacto.", + "message.saved": "Guardado.", + "message.share-url": "Esta es la URL pública para {target}.", + "message.team-already-member": "Ya eres miembro de este equipo.", + "message.team-not-found": "Equipo no encontrado.", + "message.team-websites-info": "Las analíticas de tus sitios web pueden ser vistas por cualquier miembro del equipo.", + "message.tracking-code": "Código de rastreo", + "message.user-deleted": "Usuario eliminado.", + "message.visitor-log": "Visitante desde {country} usando {browser} en {os} {device}" +} diff --git a/lang/es-MX.json b/src/lang/es-MX.json similarity index 67% rename from lang/es-MX.json rename to src/lang/es-MX.json index 999c1d8f..499b2533 100644 --- a/lang/es-MX.json +++ b/src/lang/es-MX.json @@ -2,23 +2,34 @@ "label.access-code": "Código de acceso", "label.actions": "Acciones", "label.activity-log": "Registro de actividad", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Nuevo sitio web", "label.admin": "Administrador", + "label.after": "After", "label.all": "Todos", "label.all-time": "Todos los tiempos", "label.analytics": "Analíticas", + "label.average": "Average", "label.average-visit-time": "Tiempo promedio de visita", "label.back": "Atrás", + "label.before": "Before", "label.bounce-rate": "Porcentaje de rebote", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Navegadores", "label.cancel": "Cancelar", "label.change-password": "Cambiar contraseña", "label.cities": "Ciudades", + "label.city": "City", "label.clear-all": "Limpiar todo", "label.confirm": "Confirmar", "label.confirm-password": "Confirmar contraseña", + "label.contains": "Contains", "label.continue": "Continuar", "label.countries": "Países", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Crear equipo", "label.create-user": "Crear usuario", "label.created": "Creado", @@ -26,23 +37,43 @@ "label.custom-range": "Intervalo personalizado", "label.dashboard": "Panel de control", "label.data": "Datos", + "label.date": "Date", "label.date-range": "Intervalo de fechas", + "label.day": "Day", "label.default-date-range": "Intervalo por defecto", "label.delete": "Eliminar", "label.delete-team": "Eliminar team", "label.delete-user": "Eliminar usuario", "label.delete-website": "Eliminar sitio", + "label.description": "Description", "label.desktop": "Escritorio", "label.details": "Detalles", + "label.device": "Device", "label.devices": "Dispositivos", "label.dismiss": "Ignorar", + "label.does-not-contain": "Does not contain", "label.domain": "Dominio", + "label.dropoff": "Dropoff", "label.edit": "Editar", "label.edit-dashboard": "Editar panel", "label.enable-share-url": "Habilitar compartir URL", + "label.event": "Evento", + "label.event-data": "Event data", "label.events": "Eventos", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Combinado", "label.filter-raw": "Personalizado", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Unir", "label.join-team": "Unir a equipo", "label.language": "Idioma", @@ -52,46 +83,64 @@ "label.last-hours": "Últimas {x} horas", "label.leave": "Abandonar", "label.leave-team": "Abandonar equipo", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Iniciar sesión", "label.logout": "Cerrar sesión", + "label.max": "Max", "label.members": "Miembros", + "label.min": "Min", "label.mobile": "Móvil", "label.more": "Más", + "label.my-websites": "My websites", "label.name": "Nombre", "label.new-password": "Nueva contraseña", "label.none": "Ninguno", - "label.operating-systems": "Sistemas operativos", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Propietario", + "label.page-of": "Page {current} of {total}", "label.page-views": "Vistas", + "label.pageTitle": "Page title", "label.pages": "Páginas", "label.password": "Contraseña", "label.powered-by": "Analíticas de {name}", "label.profile": "Perfil", "label.queries": "Consultas", + "label.query": "Query", "label.query-parameters": "Parámetros de petición", "label.realtime": "Tiempo real", + "label.referrer": "Referrer", "label.referrers": "Referido desde", "label.refresh": "Actualizar", "label.regenerate": "Regenerar", + "label.region": "Region", "label.regions": "Regiones", "label.remove": "Quitar", + "label.reports": "Reports", "label.required": "Obligatorio", "label.reset": "Reiniciar", "label.reset-website": "Reiniciar estadísticas", + "label.retention": "Retention", "label.role": "Rol", + "label.run-query": "Run query", "label.save": "Guardar", "label.screens": "Pantallas", + "label.select-date": "Select date", "label.select-website": "Seleccionar sitio web", "label.sessions": "Sesiones", "label.settings": "Configuraciones", "label.share-url": "Compartir URL", "label.single-day": "Día", + "label.sum": "Sum", "label.tablet": "Tableta", "label.team": "Equipo", "label.team-guest": "Invitado de equipo", "label.team-id": "ID de equipo", "label.team-member": "Miembro de equipo", + "label.team-name": "Team name", "label.team-owner": "Admin. del equipo", + "label.team-websites": "Team websites", "label.teams": "Equipos", "label.theme": "Tema", "label.this-month": "Este mes", @@ -101,24 +150,37 @@ "label.title": "Título", "label.today": "Hoy", "label.toggle-charts": "Alternar gráficas", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Código de rastreo", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Visitantes únicos", "label.unknown": "Desconocida", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "Usuario", "label.username": "Nombre de usuario", "label.users": "Usuarios", + "label.value": "Value", "label.view": "Visualizar", "label.view-details": "Ver detalles", + "label.view-only": "View only", "label.views": "Vistas", "label.visitors": "Visitantes", + "label.website": "Website", "label.website-id": "ID del sitio web", "label.websites": "Sitios", + "label.window": "Window", "label.yesterday": "Ayer", "message.active-users": "{x} {x, plural, one {activo} other {activos}}", "message.confirm-delete": "¿Seguro que quieres eliminar {target}?", "message.confirm-leave": "¿Seguro que quieres abandonar {target}?", "message.confirm-reset": "¿Seguro que quieres BORRAR las analíticas de {target}?", - "message.delete-website": "Eliminar sitio web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Toda la información relacionada será eliminada.", "message.error": "Algo falló.", "message.event-log": "{event} en {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nombre de usuario o contraseña incorrectos.", "message.invalid-domain": "Dominio inválido", "message.min-password-length": "Longitud mínima de {n} caracteres", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "No hay información disponible.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Las contraseñas no coinciden", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "Este equipo no tiene ningún sitio web configurado.", "message.no-teams": "No has creado ningún equipo.", "message.no-users": "No hay usuarios.", + "message.no-websites-configured": "No tienes ningún sitio configurado.", "message.page-not-found": "Página no encontrada", - "message.reset-website": "Reiniciar estadísticas", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Todas las estadísticas de esta página serán eliminadas, pero el código de rastreo permanecerá intacto.", "message.saved": "Guardado.", "message.share-url": "Esta es la URL compartida públicamente para {target}.", "message.team-already-member": "Ya eres miembro de este equipo.", "message.team-not-found": "Equipo no encontrado.", + "message.team-websites-info": "Las analíticas de tus sitios pueden verse por cualquier miembro del equipo.", "message.tracking-code": "Código de rastreo", "message.user-deleted": "Usuario eliminado.", - "message.visitor-log": "Visitante desde {country} usando {browser} en {os} {device}", - "messages.no-team-websites": "Este equipo no tiene ningún sitio web configurado.", - "messages.no-websites-configured": "No tienes ningún sitio configurado.", - "messages.team-websites-info": "Las analíticas de tus sitios pueden verse por cualquier miembro del equipo." + "message.visitor-log": "Visitante desde {country} usando {browser} en {os} {device}" } diff --git a/lang/fa-IR.json b/src/lang/fa-IR.json similarity index 69% rename from lang/fa-IR.json rename to src/lang/fa-IR.json index 94330ce3..b263a7d1 100644 --- a/lang/fa-IR.json +++ b/src/lang/fa-IR.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "اقدامات", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "افزودن وب‌سایت", "label.admin": "مدیر", + "label.after": "After", "label.all": "همه", "label.all-time": "همه زمان", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "میانگین زمان بازدید", "label.back": "برگشت", + "label.before": "Before", "label.bounce-rate": "نرخ Bounce", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "مروگرها", "label.cancel": "انصراف", "label.change-password": "تغییر رمز", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "تایید رمز", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "کشورها", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "محدوده‌ی دلخواه", "label.dashboard": "داشبورد", "label.data": "Data", + "label.date": "Date", "label.date-range": "محدوده‌ی تاریخ", + "label.day": "Day", "label.default-date-range": "محدوده‌ی پیشفرض تاریخ", "label.delete": "حذف", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "حذف وب‌سایت", + "label.description": "Description", "label.desktop": "دسکتاپ", "label.details": "Details", + "label.device": "Device", "label.devices": "دستگاه‌ها", "label.dismiss": "رد کردن", + "label.does-not-contain": "Does not contain", "label.domain": "دامنه", + "label.dropoff": "Dropoff", "label.edit": "ویرایش", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "فعال کردن اشتراک گذاری URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "رویدادها", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "ترکیب شده", "label.filter-raw": "خام", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "زبان", @@ -52,46 +83,64 @@ "label.last-hours": "لیست {x} ساعت گذشته", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "ورود", "label.logout": "خروج", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "موبایل", "label.more": "بیشتر", + "label.my-websites": "My websites", "label.name": "نام", "label.new-password": "رمز جدید", "label.none": "None", - "label.operating-systems": "سیستم‌عامل‌ها", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "ایجاد شده توسط", + "label.page-of": "Page {current} of {total}", "label.page-views": "بازدید صفحه", + "label.pageTitle": "Page title", "label.pages": "صفحه‌ها", "label.password": "رمز", "label.powered-by": "قدرت گرفته توسط {name}", "label.profile": "پروفایل", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "آمار زنده", + "label.referrer": "Referrer", "label.referrers": "ارجاع دهندگان", "label.refresh": "به‌روزرسانی", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "ضروری", "label.reset": "بازنشانی", "label.reset-website": "بازنشانی آمار", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "ذخیره", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "تنظیمات", "label.share-url": "به اشتراک گذاری URL", "label.single-day": "یک روز", + "label.sum": "Sum", "label.tablet": "تبلت", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "تم", "label.this-month": "این ماه", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "امروز", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "کد رهگیری", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "بازدیدکننده‌های یکتا", "label.unknown": "ناشناخته", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "نام کاربری", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "مشاهده‌ی جزئیات", + "label.view-only": "View only", "label.views": "بازدید", "label.visitors": "بازدیدکننده", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "وب‌سایت‌ها", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} هم اکنون {x, plural, one {یک} other {از میان}}", "message.confirm-delete": "آیا مطمئن هستید می‌خواهید {target} را حذف کنید?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "آیا از بازنشانی آمار {target} مطمئن هستید?", - "message.delete-website": "حذف وب‌سایت", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "همه‌ی داده‌های مرتبط هم حذف خواهد شد.", "message.error": "مشکلی پیش آمده است.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "نام کاربری / رمز نادرست است.", "message.invalid-domain": "دامنه‌ی نامعتبر", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "اطلاعاتی موجود نیست.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "رمزها یکسان نیستند", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "شما هیچ وب‌سایتی را پیکربندی نکرده‌اید.", "message.page-not-found": "صفحه یافت نشد.", - "message.reset-website": "بازنشانی آمار", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "تمامی آمارهای این وب‌سایت حذف خواهد شد اما tracking code بدون تغییر باقی می‌ماند.", "message.saved": "با موفقیت ذخیره شد.", "message.share-url": "این URL به اشتراک گذاشته شده عمومی برای {target} است.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "کد رهگیری", "message.user-deleted": "User deleted.", - "message.visitor-log": "بازدیدکننده از کشور {country} با مروگر {browser} در {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "شما هیچ وب‌سایتی را پیکربندی نکرده‌اید.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "بازدیدکننده از کشور {country} با مروگر {browser} در {os} {device}" } diff --git a/lang/fi-FI.json b/src/lang/fi-FI.json similarity index 67% rename from lang/fi-FI.json rename to src/lang/fi-FI.json index 28ef3e72..9e9c1de0 100644 --- a/lang/fi-FI.json +++ b/src/lang/fi-FI.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Toiminnat", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Lisää verkkosivu", "label.admin": "Järjestelmänvalvoja", + "label.after": "After", "label.all": "Kaikki", "label.all-time": "Alusta lähtien", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Keskimääräinen vierailuaika", "label.back": "Takaisin", + "label.before": "Before", "label.bounce-rate": "Välitön poistuminen", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Selaimet", "label.cancel": "Peruuta", "label.change-password": "Vaihda salasana", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Vahvista salasana", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Maat", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Mukautettu ajanjakso", "label.dashboard": "Ohjauspaneeli", "label.data": "Data", + "label.date": "Date", "label.date-range": "Ajanjakso", + "label.day": "Day", "label.default-date-range": "Oletusajanjakso", "label.delete": "Poista", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Poista verkkosivu", + "label.description": "Description", "label.desktop": "Pöytäkone", "label.details": "Details", + "label.device": "Device", "label.devices": "Laitteet", "label.dismiss": "Hylkää", + "label.does-not-contain": "Does not contain", "label.domain": "Verkkotunnus", + "label.dropoff": "Dropoff", "label.edit": "Muokkaa", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Ota jakamisen URL-osoite käyttöön", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Tapahtumat", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Yhdistetty", "label.filter-raw": "Käsittelemätön", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Kieli", @@ -52,46 +83,64 @@ "label.last-hours": "Viimeisimmät {x} tuntia", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Kirjaudu sisään", "label.logout": "Kirjaudu ulos", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Puhelin", "label.more": "Lisää", + "label.my-websites": "My websites", "label.name": "Nimi", "label.new-password": "Uusi salasana", "label.none": "None", - "label.operating-systems": "Käyttöjärjestelmät", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Omistaja", + "label.page-of": "Page {current} of {total}", "label.page-views": "Sivun näyttökerrat", + "label.pageTitle": "Page title", "label.pages": "Sivut", "label.password": "Salasana", "label.powered-by": "Voimanlähteenä {name}", "label.profile": "Profiili", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Juuri nyt", + "label.referrer": "Referrer", "label.referrers": "Viittaajat", "label.refresh": "Päivitä", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Vaaditaan", "label.reset": "Nollaa", "label.reset-website": "Nollaa tilastot", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Tallenna", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Asetukset", "label.share-url": "Jaa URL", "label.single-day": "Yksi päivä", + "label.sum": "Sum", "label.tablet": "Tabletti", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Teema", "label.this-month": "Tämä kuukausi", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Tänään", "label.toggle-charts": "Kytke kaaviot päälle/pois", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Seurantakoodi", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Yksittäiset kävijät", "label.unknown": "Tuntematon", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Käyttäjänimi", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Katso tiedot", + "label.view-only": "View only", "label.views": "Näyttökerrat", "label.visitors": "Vierailijat", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Verkkosivut", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} {x, plural, one {vierailija} other {vierailijaa}}", "message.confirm-delete": "Haluatko varmasti poistaa sivuston {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Haluatko varmasti poistaa sivuston {target} tilastot?", - "message.delete-website": "Poista verkkosivu", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Kaikki siihen liittyvät tiedot poistetaan.", "message.error": "Jotain meni pieleen.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Väärä käyttäjänimi/salasana.", "message.invalid-domain": "Virheellinen verkkotunnus", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Tietoja ei ole käytettävissä.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Salasanat eivät täsmää", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Sinulla ei ole määritettyjä verkkosivustoja.", "message.page-not-found": "Sivua ei löydetty.", - "message.reset-website": "Nollaa tilastot", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Kaikki sivuston tilastot poistetaan, mutta seurantakoodi pysyy muuttumattomana.", "message.saved": "Tallennettu onnistuneesti.", "message.share-url": "Tämä on julkisesti jaettu URL sivustolle {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Seurantakoodi", "message.user-deleted": "User deleted.", - "message.visitor-log": "Vierailija maasta {country} selaimella {browser} laitteella {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Sinulla ei ole määritettyjä verkkosivustoja.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Vierailija maasta {country} selaimella {browser} laitteella {os} {device}" } diff --git a/lang/fo-FO.json b/src/lang/fo-FO.json similarity index 66% rename from lang/fo-FO.json rename to src/lang/fo-FO.json index 63e7742f..6259a555 100644 --- a/lang/fo-FO.json +++ b/src/lang/fo-FO.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Gerðir", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Legg heimasíðu afturat", "label.admin": "Fyrisitari", + "label.after": "After", "label.all": "Alt", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Miðal vitjurnartíð ", "label.back": "Aftur", + "label.before": "Before", "label.bounce-rate": "Bounce prosenttal", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Kagar", "label.cancel": "Strika", "label.change-password": "Skift loyniorð", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Vátta loyniorð", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Lond", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Tillaga spenni", "label.dashboard": "Yvirlitsskíggi", "label.data": "Data", + "label.date": "Date", "label.date-range": "Vel dato", + "label.day": "Day", "label.default-date-range": "Forsett dato", "label.delete": "Sletta", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Sletta heimasíðu", + "label.description": "Description", "label.desktop": "Borðtelda", "label.details": "Details", + "label.device": "Device", "label.devices": "Tóleindir", "label.dismiss": "Lat fara", + "label.does-not-contain": "Does not contain", "label.domain": "Økisnavn", + "label.dropoff": "Dropoff", "label.edit": "Ger broyting", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Virkja deili leinki", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Hendingar/tiltøk", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Samansett", "label.filter-raw": "Óviðgjørt", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Seinastu {x} tímarnar", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Rita inn", "label.logout": "Rita út", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Telefon", "label.more": "Meira", + "label.my-websites": "My websites", "label.name": "Navn", "label.new-password": "Nýtt loyniorð", "label.none": "None", - "label.operating-systems": "Stýrikervir", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Opnaðar síðir", + "label.pageTitle": "Page title", "label.pages": "Síðir", "label.password": "Loyniorð", "label.powered-by": "Powered by {name}", "label.profile": "Vangi", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Beinleiðis", + "label.referrer": "Referrer", "label.referrers": "Framsendingar", "label.refresh": "Endurskapa", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Kravt", "label.reset": "Nulstilla", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Goym", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Stillingar", "label.share-url": "Deil leinku", "label.single-day": "Einkultur dagur", + "label.sum": "Sum", "label.tablet": "Teldil", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Hendan mánan", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Í dag", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Spori kota", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Einsýna vitjanir", "label.unknown": "Ókent", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Brúkaranavn", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Vís frágreiðing", + "label.view-only": "View only", "label.views": "Sýningar", "label.visitors": "Vitjandi", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Heimasíður", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} í løtuni {x, plural, one {vitjandi} other { vitjandi }}", "message.confirm-delete": "Ert tú sikkur at tú ynskir at strika {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Sletta heimasíðu", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Øll data ið er knýtt at verður eisini strika.", "message.error": "Okkurt bleiv gali.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Skeivt brúkaranavn/loyniorð.", "message.invalid-domain": "Ógilt økisnavn", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Einki data tøk.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Loyniorðini eru ikki eins", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Tú hevur ongar heimasíður stillaða til.", "message.page-not-found": "Síðan bleiv ikki funnin.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Goymt.", "message.share-url": "Hettar er tann almenna leinkan av {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Spori kota", "message.user-deleted": "User deleted.", - "message.visitor-log": "Vitjandi frá {country} brúkar {browser} á {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Tú hevur ongar heimasíður stillaða til.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Vitjandi frá {country} brúkar {browser} á {os} {device}" } diff --git a/lang/fr-FR.json b/src/lang/fr-FR.json similarity index 66% rename from lang/fr-FR.json rename to src/lang/fr-FR.json index 162a6f8f..558c1cd2 100644 --- a/lang/fr-FR.json +++ b/src/lang/fr-FR.json @@ -2,23 +2,34 @@ "label.access-code": "Code d'accès", "label.actions": "Actions", "label.activity-log": "Journal d'activité", + "label.add": "Ajouter", + "label.add-description": "Ajouter une description", "label.add-website": "Ajouter un site", "label.admin": "Administrateur", + "label.after": "Après", "label.all": "Tout", "label.all-time": "Toutes les données", "label.analytics": "Analytics", + "label.average": "Moyenne", "label.average-visit-time": "Temps de visite moyen", "label.back": "Retour", + "label.before": "Avant", "label.bounce-rate": "Taux de rebond", + "label.breakdown": "Répartition", + "label.browser": "Browser", "label.browsers": "Navigateurs", "label.cancel": "Annuler", "label.change-password": "Changer le mot de passe", "label.cities": "Villes", + "label.city": "City", "label.clear-all": "Réinitialiser", "label.confirm": "Confirmer", "label.confirm-password": "Confirmation du mot de passe", + "label.contains": "Contient", "label.continue": "Continuer", "label.countries": "Pays", + "label.country": "Country", + "label.create-report": "Créer un rapport", "label.create-team": "Créer une équipe", "label.create-user": "Créer un utilisateur", "label.created": "Créé", @@ -26,23 +37,43 @@ "label.custom-range": "Période personnalisée", "label.dashboard": "Tableau de bord", "label.data": "Données", + "label.date": "Date", "label.date-range": "Période", + "label.day": "Day", "label.default-date-range": "Période par défaut", "label.delete": "Supprimer", "label.delete-team": "Supprimer l'équipe", "label.delete-user": "Supprimer l'utilisateur", "label.delete-website": "Supprimer le site", + "label.description": "Description", "label.desktop": "Ordinateur", "label.details": "Détails", + "label.device": "Device", "label.devices": "Appareils", "label.dismiss": "Ignorer", + "label.does-not-contain": "Ne contient pas", "label.domain": "Domaine", + "label.dropoff": "Dropoff", "label.edit": "Modifier", "label.edit-dashboard": "Modifier le tableau de bord", "label.enable-share-url": "Activer l'URL de partage", + "label.event": "Event", + "label.event-data": "Données d'événements", "label.events": "Événements", + "label.false": "Faux", + "label.field": "Champ", + "label.fields": "Champs", "label.filter-combined": "Combiné", "label.filter-raw": "Brut", + "label.filters": "Filtres", + "label.funnel": "Entonnoir", + "label.greater-than": "Supérieur à", + "label.greater-than-equals": "Supérieur ou égal à", + "label.insights": "Insights", + "label.is": "Est égal", + "label.is-not": "N'est pas égal", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Rejoindre", "label.join-team": "Rejoindre une équipe", "label.language": "Langue", @@ -52,46 +83,64 @@ "label.last-hours": "{x} dernières heures", "label.leave": "Quitter", "label.leave-team": "Quitter l'équipe", + "label.less-than": "Inférieur à", + "label.less-than-equals": "Inférieur ou égal à", "label.login": "Connexion", "label.logout": "Déconnexion", + "label.max": "Max", "label.members": "Membres", + "label.min": "Min", "label.mobile": "Téléphone", "label.more": "Plus", + "label.my-websites": "My websites", "label.name": "Nom", "label.new-password": "Nouveau mot de passe", "label.none": "Aucun·e", - "label.operating-systems": "Systèmes d'exploitation", + "label.os": "OS", + "label.overview": "Vue d'ensemble", "label.owner": "Propriétaire", + "label.page-of": "Page {current} of {total}", "label.page-views": "Pages vues", + "label.pageTitle": "Page title", "label.pages": "Pages", "label.password": "Mot de passe", "label.powered-by": "Propulsé par {name}", "label.profile": "Profil", - "label.queries": "Queries", + "label.queries": "Requêtes", + "label.query": "Requête", "label.query-parameters": "Paramètres d'URL", "label.realtime": "Temps réel", - "label.referrers": "Sources", + "label.referrer": "Referrer", + "label.referrers": "Sites référents", "label.refresh": "Rafraîchir", "label.regenerate": "Régénérer", + "label.region": "Region", "label.regions": "Régions", "label.remove": "Retirer", + "label.reports": "Rapports", "label.required": "Requis", "label.reset": "Réinitialiser", "label.reset-website": "Réinitialiser les statistiques", + "label.retention": "Retention", "label.role": "Rôle", + "label.run-query": "Éxécuter la requête", "label.save": "Enregistrer", "label.screens": "Résolutions d'écran", + "label.select-date": "Choisir une période", "label.select-website": "Choisir un site", "label.sessions": "Sessions", "label.settings": "Paramètres", "label.share-url": "URL de partage", "label.single-day": "Journée", + "label.sum": "Somme", "label.tablet": "Tablette", "label.team": "Équipe", "label.team-guest": "Invité dans l'équipe", "label.team-id": "ID d'équipe", "label.team-member": "Membre de l'équipe", + "label.team-name": "Team name", "label.team-owner": "Propriétaire de l'équipe", + "label.team-websites": "Team websites", "label.teams": "Équipes", "label.theme": "Thème", "label.this-month": "Ce mois", @@ -101,23 +150,36 @@ "label.title": "Titre", "label.today": "Aujourd'hui", "label.toggle-charts": "Afficher/Masquer les graphiques", + "label.total": "Total", + "label.total-records": "Nombre d'enregistrements", "label.tracking-code": "Code de suivi", + "label.true": "Vrai", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Visiteurs uniques", "label.unknown": "Inconnu", + "label.untitled": "Sans titre", + "label.url": "URL", + "label.urls": "URLs", "label.user": "Utilisateur", "label.username": "Nom d'utilisateur", "label.users": "Utilisateurs", + "label.value": "Valeur", "label.view": "Voir", "label.view-details": "Voir les détails", + "label.view-only": "Consultation", "label.views": "Vues", "label.visitors": "Visiteurs", + "label.website": "Website", "label.website-id": "ID de site", "label.websites": "Sites", + "label.window": "Fenêtre", "label.yesterday": "Hier", "message.active-users": "{x} {x, plural, one {visiteur} other {visiteurs}} actuellement", "message.confirm-delete": "Êtes-vous sûr de vouloir supprimer {target} ?", "message.confirm-leave": "Êtes-vous sûr de vouloir quitter {target} ?", "message.confirm-reset": "Êtes-vous sûr de vouloir réinitialiser les statistiques de {target} ?", + "message.delete-account": "Pour supprimer ce compte, taper {confirmation} ci-dessous pour confirmer.", "message.delete-website": "Pour supprimer ce site, taper {confirmation} ci-dessous pour confirmer.", "message.delete-website-warning": "Toutes les données associées seront supprimées.", "message.error": "Un problème est survenu.", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nom d'utilisateur/Mot de passe incorrect.", "message.invalid-domain": "Domaine invalide", "message.min-password-length": "Taille minimale de {n} caractères", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Aucune donnée disponible.", + "message.no-event-data": "Aucune donnée d'événement disponible.", "message.no-match-password": "Les mots de passe ne correspondent pas", - "message.no-teams": "Vous n'avez créé aucune équipe.", - "message.no-users": "Il n'y aucun utilisateur.", + "message.no-results-found": "Aucun résultat n'a été trouvé.", + "message.no-team-websites": "Cette équipe n'a aucun site.", + "message.no-teams": "Vous n'avez pas créé d'équipe.", + "message.no-users": "Aucun utilisateur.", + "message.no-websites-configured": "Vous n'avez pas configuré de site.", "message.page-not-found": "Page non trouvée.", - "message.reset-website": "Réinitialiser les statistiques", + "message.reset-website": "Pour réinitialiser ce site, taper {confirmation} ci-dessous pour confirmer.", "message.reset-website-warning": "Toutes les statistiques pour ce site seront supprimées, mais votre code de suivi restera intact.", "message.saved": "Enregistré avec succès.", "message.share-url": "Les statistiques de votre site sont accessibles publiquement sur cette URL :", "message.team-already-member": "Vous êtes déjà membre de cette équipe.", "message.team-not-found": "Équipe non trouvée.", + "message.team-websites-info": "Les sites peuvent être vus par tout utilisateur dans l'équipe.", "message.tracking-code": "Code de suivi", "message.user-deleted": "Utilisateur supprimé.", - "message.visitor-log": "Visiteur de {country} utilisant {browser} sur {os} {device}", - "messages.no-team-websites": "Cette équipe n'a aucun site.", - "messages.no-websites-configured": "Vous n'avez configuré aucun site.", - "messages.team-websites-info": "Les sites peuvent être vus par tout utilisateur dans l'équipe." + "message.visitor-log": "Visiteur de {country} utilisant {browser} sur {os} {device}" } diff --git a/lang/ga-ES.json b/src/lang/ga-ES.json similarity index 66% rename from lang/ga-ES.json rename to src/lang/ga-ES.json index a8aa0383..e6ceda8a 100644 --- a/lang/ga-ES.json +++ b/src/lang/ga-ES.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Accións", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Engadir sitio web", "label.admin": "Administradora", + "label.after": "After", "label.all": "Todo", "label.all-time": "Sempre", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Tempo medio de visita", "label.back": "Atrás", + "label.before": "Before", "label.bounce-rate": "Proporción de rebote", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Navegadores", "label.cancel": "Cancelar", "label.change-password": "Mudar contrasinal", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Confirmar contrasinal", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Países", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Rango personalizado", "label.dashboard": "Taboleiro", "label.data": "Data", + "label.date": "Date", "label.date-range": "Rango temporal", + "label.day": "Day", "label.default-date-range": "Rango temporal por defecto", "label.delete": "Eliminar", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Eliminar sitio web", + "label.description": "Description", "label.desktop": "Escritorio", "label.details": "Details", + "label.device": "Device", "label.devices": "Dispositivos", "label.dismiss": "Desbotar", + "label.does-not-contain": "Does not contain", "label.domain": "Dominio", + "label.dropoff": "Dropoff", "label.edit": "Editar", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Activar URL de compartición", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Eventos", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Combinado", "label.filter-raw": "Raw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Idioma", @@ -52,46 +83,64 @@ "label.last-hours": "Últimas {x} horas", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Acceder", "label.logout": "Pechar sesión", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Móbil", "label.more": "Máis", + "label.my-websites": "My websites", "label.name": "Nome", "label.new-password": "Novo contrasinal", "label.none": "None", - "label.operating-systems": "Sistemas operativos", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Dona", + "label.page-of": "Page {current} of {total}", "label.page-views": "Vistas de páxinas", + "label.pageTitle": "Page title", "label.pages": "Páxinas", "label.password": "Contrasinal", "label.powered-by": "Funciona grazas a {name}", "label.profile": "Perfil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Agora mesmo", + "label.referrer": "Referrer", "label.referrers": "Orixes", "label.refresh": "Actualizar", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Requerido", "label.reset": "Restablecer", - "label.reset-website": "Restablecer estatísticas", + "label.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Gardar", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Axustes", "label.share-url": "Compartir URL", "label.single-day": "Un só día", + "label.sum": "Sum", "label.tablet": "Tableta", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Decorado", "label.this-month": "Este mes", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Hoxe", "label.toggle-charts": "Activación das gráficas", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Código de seguimento", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Visitas únicas", "label.unknown": "Descoñecido", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Identificador", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Ver detalles", + "label.view-only": "View only", "label.views": "Visualizacións", "label.visitors": "Visitantes", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Sitios web", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} actual {x, plural, one {visitante} other {visitantes}}", "message.confirm-delete": "Tes a certeza de querer eliminar {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Tes a certeza de querer restablecer as estatísticas de {target}?", - "message.delete-website": "Eliminar sitio web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Tamén serán borrados tódolos datos asociados.", "message.error": "Houbo un fallo.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Credenciais incorrectas.", "message.invalid-domain": "Dominio non válido", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Sen datos dispoñibles.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Non concordan os contrasinais", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Non tes sitios web configurados.", "message.page-not-found": "Páxina non atopada.", - "message.reset-website": "Restablecer estatísticas", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Vanse eliminar tódalas estatísticas deste sitio web, pero o código de seguimento permanecerá sen cambios.", "message.saved": "Gardouse correctamente.", "message.share-url": "Este é o URL da compartición pública de {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Código de seguimento", "message.user-deleted": "User deleted.", - "message.visitor-log": "Visitante desde {country} usando {browser} en {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Non tes sitios web configurados.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Visitante desde {country} usando {browser} en {os} {device}" } diff --git a/lang/he-IL.json b/src/lang/he-IL.json similarity index 67% rename from lang/he-IL.json rename to src/lang/he-IL.json index f9284e17..fd3e0b8b 100644 --- a/lang/he-IL.json +++ b/src/lang/he-IL.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "פעולות", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "הוספת אתר", "label.admin": "מנהל", + "label.after": "After", "label.all": "הכל", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "זמן ביקור ממוצע", "label.back": "חזרה", + "label.before": "Before", "label.bounce-rate": "Bounce rate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "דפדפנים", "label.cancel": "ביטול", "label.change-password": "שינוי סיסמה", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "אישור סיסמה", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "מדינות", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "טווח מותאם", "label.dashboard": "דשבורד", "label.data": "Data", + "label.date": "Date", "label.date-range": "טווח תאריכים", + "label.day": "Day", "label.default-date-range": "טווח תאריכים בברירת מחדל", "label.delete": "הסרה", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "הסרת אתר", + "label.description": "Description", "label.desktop": "דסקטופ", "label.details": "Details", + "label.device": "Device", "label.devices": "מכשירים", "label.dismiss": "שיחרור", + "label.does-not-contain": "Does not contain", "label.domain": "דומיין", + "label.dropoff": "Dropoff", "label.edit": "עריכה", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "הפעלת URL שיתוף", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "אירועים", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "משותף", "label.filter-raw": "גולמי", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "{x} שעות אחרונות", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "התחברות", "label.logout": "התנתקות", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "מובייל", "label.more": "עוד", + "label.my-websites": "My websites", "label.name": "שם", "label.new-password": "סיסמה חדשה", "label.none": "None", - "label.operating-systems": "מערכות הפעלה", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "צפיות בדפים", + "label.pageTitle": "Page title", "label.pages": "דפים", "label.password": "סיסמה", "label.powered-by": "Powered by {name}", "label.profile": "פרופיל", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "זמן אמת", + "label.referrer": "Referrer", "label.referrers": "מפנים", "label.refresh": "רענון", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "נדרש", "label.reset": "איפוס", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "שמירה", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "הגדרות", "label.share-url": "שיתוף URL", "label.single-day": "יום בודד", + "label.sum": "Sum", "label.tablet": "טאבלט", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "החודש", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "היום", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "קוד מעקב", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "מבקרים ייחודיים", "label.unknown": "לא ידוע", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "שם משתמש", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "פרטים נוספים", + "label.view-only": "View only", "label.views": "צפיות", "label.visitors": "מבקרים", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "אתרים", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} נוכחיים {x, plural, one {מבקר} other {מבקרים}}", "message.confirm-delete": "האם באמת למחוק את {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "הסרת אתר", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "כל המידע המקושר יימחק", "message.error": "משהו השתבש", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "שם משתמש או סיסמה לא נכונים", "message.invalid-domain": "דומיין לא תקין", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "אין מידע זמין", + "message.no-event-data": "No event data is available.", "message.no-match-password": "סיסמאות לא תואמות", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "לא מוגדרים אתרים", "message.page-not-found": "דף לא נמצא", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "נשמר בהצלחה", "message.share-url": "זהו URL ציבורי עבור {target}", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "קוד מעקב", "message.user-deleted": "User deleted.", - "message.visitor-log": "מבקר ממדינת {country} משתמבש בדפדפן {browser} ב-{os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "לא מוגדרים אתרים", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "מבקר ממדינת {country} משתמבש בדפדפן {browser} ב-{os} {device}" } diff --git a/lang/hi-IN.json b/src/lang/hi-IN.json similarity index 71% rename from lang/hi-IN.json rename to src/lang/hi-IN.json index 794e0cd5..6e268aa6 100644 --- a/lang/hi-IN.json +++ b/src/lang/hi-IN.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "कार्य", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "वेबसाइट", "label.admin": "प्रशासक", + "label.after": "After", "label.all": "सब", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "औसत दृश्य समय", "label.back": "पीछे", + "label.before": "Before", "label.bounce-rate": "उछाल दर", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "वेब ब्राउज़र", "label.cancel": "रद्द करें", "label.change-password": "पासवर्ड बदलें", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "पासवर्ड की पुष्टि कीजिये", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "देश", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "कस्टम रेंज", "label.dashboard": "नियंत्रण-पट्ट", "label.data": "Data", + "label.date": "Date", "label.date-range": "तिथि सीमा", + "label.day": "Day", "label.default-date-range": "डिफ़ॉल्ट तिथि सीमा", "label.delete": "खाता हटाएं", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "वेबसाइट हटाएं", + "label.description": "Description", "label.desktop": "डेस्कटॉप", "label.details": "Details", + "label.device": "Device", "label.devices": "उपकरण", "label.dismiss": "खारिज कीजिये", + "label.does-not-contain": "Does not contain", "label.domain": "डोमेन", + "label.dropoff": "Dropoff", "label.edit": "संपादित करें", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "शेयर URL सक्षम करें", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "स्पर्धाएँ", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "संयुक्त", "label.filter-raw": "रॉ", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "पिछले {x} घंटे", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "लॉग इन", "label.logout": "लॉग आउट", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "मोबाइल फोन", "label.more": "और", + "label.my-websites": "My websites", "label.name": "नाम", "label.new-password": "नया पासवर्ड", "label.none": "None", - "label.operating-systems": "ऑपरेटिंग सिस्टम", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "पृष्ठ दृश्य", + "label.pageTitle": "Page title", "label.pages": "पृष्ठों", "label.password": "पासवर्ड", "label.powered-by": "{name} द्वारा संचालित", "label.profile": "प्रोफ़ाइल", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "वास्तव काल", + "label.referrer": "Referrer", "label.referrers": "सन्दर्भदाता", "label.refresh": "रिफ्रेश", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "अपेक्षित", "label.reset": "रीसेट", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "सहेजें", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "समायोजन", "label.share-url": "यूआरएल साझा करें", "label.single-day": "एक दिन", + "label.sum": "Sum", "label.tablet": "टैबलेट", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "इस महीने", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "आज", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "ट्रैकिंग कोड", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "अद्वितीय आगंतुकों", "label.unknown": "अज्ञात", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "उपयोगकर्ता नाम", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "विवरण देखें", + "label.view-only": "View only", "label.views": "दृश्य", "label.visitors": "आगंतुकों", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "वेबसाइटों", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} मौजूद {x, plural, one {आगंतुक} other {आगंतुकों}}", "message.confirm-delete": "क्या आप वाकई में {target} हटाना चाहते हैं?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "वेबसाइट हटाएं", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।", "message.error": "कुछ गलत हो गया।", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "ग़लत उपयोगकर्ता नाम / पासवर्ड।", "message.invalid-domain": "अमान्य डोमेन", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "कोई डेटा उपलब्ध नहीं है।", + "message.no-event-data": "No event data is available.", "message.no-match-password": "पासवर्ड मेल नहीं खाते", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "आपके पास कोई वेबसाइट कॉन्फ़िगर नहीं है।", "message.page-not-found": "पृष्ठ नहीं मिला।", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "सफलतापूर्वक संचित कर लिया गया है।", "message.share-url": "यह {target} के लिए सार्वजनिक रूप से साझा किया गया URL है।", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "ट्रैकिंग कोड", "message.user-deleted": "User deleted.", - "message.visitor-log": "{country} का आगंतुक, जो {browser} का उपयोग करता है, {os} यन्त्र पर", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "आपके पास कोई वेबसाइट कॉन्फ़िगर नहीं है।", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "{country} का आगंतुक, जो {browser} का उपयोग करता है, {os} यन्त्र पर" } diff --git a/src/lang/hr-HR.json b/src/lang/hr-HR.json new file mode 100644 index 00000000..ecde7100 --- /dev/null +++ b/src/lang/hr-HR.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Access code", + "label.actions": "Actions", + "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "Dodaj web stranicu", + "label.admin": "Administrator", + "label.after": "After", + "label.all": "Sve", + "label.all-time": "Svo vrijeme", + "label.analytics": "Analytics", + "label.average": "Average", + "label.average-visit-time": "Average visit time", + "label.back": "Natrag ", + "label.before": "Before", + "label.bounce-rate": "Bounce rate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Browsers", + "label.cancel": "Odustani", + "label.change-password": "Promijeni lozinku", + "label.cities": "Cities", + "label.city": "City", + "label.clear-all": "Clear all", + "label.confirm": "Confirm", + "label.confirm-password": "Potvrdi lozinku", + "label.contains": "Contains", + "label.continue": "Continue", + "label.countries": "Countries", + "label.country": "Country", + "label.create-report": "Create report", + "label.create-team": "Create team", + "label.create-user": "Create user", + "label.created": "Created", + "label.current-password": "Trenutna lozinka", + "label.custom-range": "Prilagođeni raspon", + "label.dashboard": "Nadzorna ploča", + "label.data": "Data", + "label.date": "Date", + "label.date-range": "Raspon datuma", + "label.day": "Day", + "label.default-date-range": "Zadani datumski raspon", + "label.delete": "Obriši", + "label.delete-team": "Delete team", + "label.delete-user": "Delete user", + "label.delete-website": "Obriši web stranicu", + "label.description": "Description", + "label.desktop": "Desktop", + "label.details": "Details", + "label.device": "Device", + "label.devices": "Devices", + "label.dismiss": "Odbaci", + "label.does-not-contain": "Does not contain", + "label.domain": "Domena", + "label.dropoff": "Dropoff", + "label.edit": "Uredi", + "label.edit-dashboard": "Edit dashboard", + "label.enable-share-url": "Omogući dijeljenje poveznice", + "label.event": "Event", + "label.event-data": "Podaci događaja", + "label.events": "Events", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", + "label.filter-combined": "Combined", + "label.filter-raw": "Raw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Join", + "label.join-team": "Join team", + "label.language": "Jezik", + "label.languages": "Languages", + "label.laptop": "Laptop", + "label.last-days": "Zadnjih {x} dana", + "label.last-hours": "Zadnjih {x} sati", + "label.leave": "Leave", + "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", + "label.login": "Prijava", + "label.logout": "Odjava", + "label.max": "Max", + "label.members": "Members", + "label.min": "Min", + "label.mobile": "Mobile", + "label.more": "Više", + "label.my-websites": "My websites", + "label.name": "Ime", + "label.new-password": "Nova lozinka", + "label.none": "Ništa", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "Vlasnik", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Page views", + "label.pageTitle": "Page title", + "label.pages": "Pages", + "label.password": "Lozinka", + "label.powered-by": "Powered by {name}", + "label.profile": "Profil", + "label.queries": "Queries", + "label.query": "Query", + "label.query-parameters": "Query parameters", + "label.realtime": "Stvarno vrijeme", + "label.referrer": "Referrer", + "label.referrers": "Referrers", + "label.refresh": "Osvježi", + "label.regenerate": "Regenerate", + "label.region": "Region", + "label.regions": "Regions", + "label.remove": "Remove", + "label.reports": "Reports", + "label.required": "Potrebna", + "label.reset": "Resetirati", + "label.reset-website": "Resetirati web stranicu", + "label.retention": "Retention", + "label.role": "Role", + "label.run-query": "Run query", + "label.save": "Spremi", + "label.screens": "Screens", + "label.select-date": "Select date", + "label.select-website": "Select website", + "label.sessions": "Sessions", + "label.settings": "Postavke", + "label.share-url": "Podijeli poveznicu", + "label.single-day": "Jedan dan", + "label.sum": "Sum", + "label.tablet": "Tablet", + "label.team": "Team", + "label.team-guest": "Team guest", + "label.team-id": "Team ID", + "label.team-member": "Team member", + "label.team-name": "Team name", + "label.team-owner": "Team owner", + "label.team-websites": "Team websites", + "label.teams": "Teams", + "label.theme": "Tema", + "label.this-month": "Ovaj mjesec", + "label.this-week": "Ovaj tjedan", + "label.this-year": "Ova godina", + "label.timezone": "Vremenska zona", + "label.title": "Title", + "label.today": "Danas", + "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Kod za praćenje", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", + "label.unique-visitors": "Unique visitors", + "label.unknown": "Nepoznato", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "User", + "label.username": "Korisničko ime", + "label.users": "Users", + "label.value": "Value", + "label.view": "View", + "label.view-details": "Pogledaj detalje", + "label.view-only": "View only", + "label.views": "Views", + "label.visitors": "Visitors", + "label.website": "Website", + "label.website-id": "Website ID", + "label.websites": "Web stranice", + "label.window": "Window", + "label.yesterday": "Jučer", + "message.active-users": "{x} Trenutno {x, plural, one {posjetitelj} other {posjetitelja}}", + "message.confirm-delete": "Jeste li sigurni da želite obrisati {target}?", + "message.confirm-leave": "Are you sure you want to leave {target}?", + "message.confirm-reset": "Jeste li sigurni da želite resetirati {target}'s statistiku?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", + "message.delete-website-warning": "All website data will be deleted.", + "message.error": "Something went wrong.", + "message.event-log": "{event} on {url}", + "message.go-to-settings": "Idi u postavke", + "message.incorrect-username-password": "Neispravno korisničke ime/lozinka.", + "message.invalid-domain": "Invalid domain. Do not include http/https.", + "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", + "message.no-data-available": "Nema dostupnih podataka.", + "message.no-event-data": "No event data is available.", + "message.no-match-password": "Passwords do not match.", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", + "message.no-teams": "You have not created any teams.", + "message.no-users": "There are no users.", + "message.no-websites-configured": "You do not have any websites configured.", + "message.page-not-found": "Stranica nije pronađena.", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", + "message.reset-website-warning": "All statistics for this website will be deleted, but your settings will remain intact.", + "message.saved": "Saved.", + "message.share-url": "Ovo je javno dijeljena poveznica za {target}.", + "message.team-already-member": "You are already a member of the team.", + "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", + "message.tracking-code": "To track stats for this website, place the following code in the ... section of your HTML.", + "message.user-deleted": "User deleted.", + "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}" +} diff --git a/lang/hu-HU.json b/src/lang/hu-HU.json similarity index 67% rename from lang/hu-HU.json rename to src/lang/hu-HU.json index 803a2332..0401afff 100644 --- a/lang/hu-HU.json +++ b/src/lang/hu-HU.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Műveletek", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Weboldal hozzáadása", "label.admin": "Adminisztrátor", + "label.after": "After", "label.all": "Összes", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Átlagos látogatási idő", "label.back": "Vissza", + "label.before": "Before", "label.bounce-rate": "Visszafordulási arány", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Böngészők", "label.cancel": "Mégsem", "label.change-password": "Jelszó módosítása", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Jelszó megerősítése", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Országok", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Egyedi tartomány", "label.dashboard": "Áttekintés", "label.data": "Data", + "label.date": "Date", "label.date-range": "Időintervallum", + "label.day": "Day", "label.default-date-range": "Alapértelmezett időintervallum", "label.delete": "Eltávolítás", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Weboldal eltávolítása", + "label.description": "Description", "label.desktop": "Asztali számítógép", "label.details": "Details", + "label.device": "Device", "label.devices": "Eszközök", "label.dismiss": "Mellőzés", + "label.does-not-contain": "Does not contain", "label.domain": "Domain", + "label.dropoff": "Dropoff", "label.edit": "Módosítás", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "URL-megosztás engedélyezése", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Események", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Összevont", "label.filter-raw": "Nyers", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Legutóbbi {x} óra", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Bejelentkezés", "label.logout": "Kijelentkezés", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Telefon", "label.more": "Bővebben", + "label.my-websites": "My websites", "label.name": "Név", "label.new-password": "Új jelszó", "label.none": "None", - "label.operating-systems": "Operációs rendszerek", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Oldalmegtekintések", + "label.pageTitle": "Page title", "label.pages": "Oldalak", "label.password": "Jelszó", "label.powered-by": "Működteti az {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Valós idejű", + "label.referrer": "Referrer", "label.referrers": "Hivatkozók", "label.refresh": "Frissítés", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Kötelező", "label.reset": "Visszaállítás", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Mentés", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Beállítások", "label.share-url": "URL megosztása", "label.single-day": "Egy nap", + "label.sum": "Sum", "label.tablet": "Táblagép", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Ezen hónap", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Ma", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Követési kód", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Egyedi látogatók", "label.unknown": "Ismeretlen", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Felhasználónév", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Részletek", + "label.view-only": "View only", "label.views": "Megtekintések", "label.visitors": "Látogatók", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Weboldalak", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} {x, plural, one {látogató} other {latógató}} jelenleg", "message.confirm-delete": "Biztos, hogy törölni szeretnéd {target} elemet?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Weboldal eltávolítása", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Minden társított adat törlésre kerül.", "message.error": "Valami baj történt.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Érvénytelen felhasználónév/jelszó.", "message.invalid-domain": "Érvénytelen domain", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Nincs rendelkezésre álló adat.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "A jelszavak nem egyeznek", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Még nem állítottál be egyetlen weboldalt sem.", "message.page-not-found": "Oldal nem található.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Sikeres mentés.", "message.share-url": "{target} nyilvánosan megosztott URL címe.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Követési kód", "message.user-deleted": "User deleted.", - "message.visitor-log": "Látógató {country} területéről, {os} {device} eszközön, {browser} böngészőből.", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Még nem állítottál be egyetlen weboldalt sem.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Látógató {country} területéről, {os} {device} eszközön, {browser} böngészőből." } diff --git a/lang/id-ID.json b/src/lang/id-ID.json similarity index 66% rename from lang/id-ID.json rename to src/lang/id-ID.json index b93172cf..d0b8a064 100644 --- a/lang/id-ID.json +++ b/src/lang/id-ID.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Aksi", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Tambah situs web", "label.admin": "Pengelola", + "label.after": "After", "label.all": "Semua", "label.all-time": "Semua waktu", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Waktu kunjungan rata-rata", "label.back": "Kembali", + "label.before": "Before", "label.bounce-rate": "Rasio pentalan", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Peramban", "label.cancel": "Batal", "label.change-password": "Ganti kata sandi", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Konfirmasi kata sandi", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Negara", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Rentang khusus", "label.dashboard": "Dasbor", "label.data": "Data", + "label.date": "Date", "label.date-range": "Rentang tanggal", + "label.day": "Day", "label.default-date-range": "Rentang tanggal bawaan", "label.delete": "Hapus", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Hapus situs web", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Perangkat", "label.dismiss": "Tutup", + "label.does-not-contain": "Does not contain", "label.domain": "Domain", + "label.dropoff": "Dropoff", "label.edit": "Sunting", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Aktifkan URL berbagi", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Perihal", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Gabungan", "label.filter-raw": "Mentah", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Bahasa", @@ -52,46 +83,64 @@ "label.last-hours": "{x} jam terakhir", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Masuk", "label.logout": "Keluar", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Ponsel", "label.more": "Lebih banyak", + "label.my-websites": "My websites", "label.name": "Nama", "label.new-password": "Kata sandi baru", "label.none": "None", - "label.operating-systems": "Sistem Operasi", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Pemilik", + "label.page-of": "Page {current} of {total}", "label.page-views": "Tampilan halaman", + "label.pageTitle": "Page title", "label.pages": "Halaman", "label.password": "Kata sandi", "label.powered-by": "Didukung oleh {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Waktu nyata", + "label.referrer": "Referrer", "label.referrers": "Perujuk", "label.refresh": "Segarkan", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Wajib", "label.reset": "Atur ulang", "label.reset-website": "Atur ulang statistik", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Simpan", "label.screens": "Layar", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Pengaturan", "label.share-url": "Bagikan URL", "label.single-day": "Sehari", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Tema", "label.this-month": "Bulan ini", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Hari ini", "label.toggle-charts": "Buka grafik", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Kode lacak", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Pengunjung unik", "label.unknown": "Tidak diketahui", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Nama pengguna", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Lihat Detil", + "label.view-only": "View only", "label.views": "Tampilan", "label.visitors": "Pengunjung", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Situs web", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} pengunjung saat ini", "message.confirm-delete": "Apakah kamu yakin ingin menghapus {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Anda yakin ingin mengatur ulang statistik {target}?", - "message.delete-website": "Hapus situs web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Semua data terkait juga akan dihapus.", "message.error": "Ada yang salah.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nama pengguna/kata sandi salah.", "message.invalid-domain": "Domain tidak valid", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Tidak ada data.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Kata sandi tidak cocok", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Anda tidak memiliki situs web yang dikonfigurasi.", "message.page-not-found": "Halaman tidak ditemukan.", - "message.reset-website": "Atur ulang statistik", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Semua statistik pada website ini akan dihapus, tetapi kode lacak akan tetap terpasang", "message.saved": "Berhasil disimpan.", "message.share-url": "Ini adalah URL yang dibagikan secara publik untuk {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Kode lacak", "message.user-deleted": "User deleted.", - "message.visitor-log": "Pengunjung dari {country} dengan {browser} di {device} {os}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Anda tidak memiliki situs web yang dikonfigurasi.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Pengunjung dari {country} dengan {browser} di {device} {os}" } diff --git a/lang/it-IT.json b/src/lang/it-IT.json similarity index 67% rename from lang/it-IT.json rename to src/lang/it-IT.json index 87c2f7c3..57d6d5ba 100644 --- a/lang/it-IT.json +++ b/src/lang/it-IT.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Azioni", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Aggiungi sito", "label.admin": "Amministratore", + "label.after": "After", "label.all": "Tutto", "label.all-time": "Sempre", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Tempo medio di visita", "label.back": "Indietro", + "label.before": "Before", "label.bounce-rate": "Frequenza di rimbalzo", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Browser", "label.cancel": "Annulla", "label.change-password": "Modifica password", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Conferma password", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Nazioni", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Personalizzato", "label.dashboard": "Pannello di Controllo", "label.data": "Data", + "label.date": "Date", "label.date-range": "Periodo", + "label.day": "Day", "label.default-date-range": "Periodo standard", "label.delete": "Elimina", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Elimina sito", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Dispositivi", "label.dismiss": "Scarta", + "label.does-not-contain": "Does not contain", "label.domain": "Dominio", + "label.dropoff": "Dropoff", "label.edit": "Modifica", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Abilita URL di condivisione", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Eventi", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Aggregati", "label.filter-raw": "Raw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Lingua", @@ -52,46 +83,64 @@ "label.last-hours": "Ultime {x} ore", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Accedi", "label.logout": "Esci", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Cellulare", "label.more": "Dettagli", + "label.my-websites": "My websites", "label.name": "Nome", "label.new-password": "Nuova password", "label.none": "None", - "label.operating-systems": "Sistemi operativi", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Proprietario", + "label.page-of": "Page {current} of {total}", "label.page-views": "Visualizzazioni di pagina", + "label.pageTitle": "Page title", "label.pages": "Pagine", "label.password": "Password", "label.powered-by": "Powered by {name}", "label.profile": "Profilo", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Tempo reale", + "label.referrer": "Referrer", "label.referrers": "Referrers", "label.refresh": "Ricarica", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Obbligatorio", "label.reset": "Reset", "label.reset-website": "Resetta le statistiche", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Salva", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Impostazioni", "label.share-url": "Condividi link", "label.single-day": "Singolo giorno", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Tema", "label.this-month": "Questo mese", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Oggi", "label.toggle-charts": "Apri/Chiudi i grafici", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Codice di tracking", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Visitatori unici", "label.unknown": "Sconosciuto", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Nome utente", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Vedi dettagli", + "label.view-only": "View only", "label.views": "Visualizzazioni", "label.visitors": "Visitatori", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Siti web", + "label.window": "Window", "label.yesterday": "Ieri", "message.active-users": "{x} {x, plural, one {visitatore} other {visitatori}} online", "message.confirm-delete": "Sei sicuro di voler eliminare {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Sei sicuro di voler azzerare le statistiche di {target}?", - "message.delete-website": "Elimina sito", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Saranno eliminati anche tutti i dati associati.", "message.error": "Si è verificato un errore.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Username o password non corretti.", "message.invalid-domain": "Dominio non valido", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Nessun dato disponibile.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Le password non corrispondono", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Non hai ancora configurato alcun sito.", "message.page-not-found": "Pagina non trovata", - "message.reset-website": "Resetta le statistiche", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Tutte le statistiche verranno cancellate per questo sito, ma il tuo codice di tracciamento rimarrà invariato.", "message.saved": "Salvato!", "message.share-url": "Questo è l'URL di condivisione per {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Codice di tracking", "message.user-deleted": "User deleted.", - "message.visitor-log": "Utenti da {country} tramite {browser} su {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Non hai ancora configurato alcun sito.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Utenti da {country} tramite {browser} su {os} {device}" } diff --git a/src/lang/ja-JP.json b/src/lang/ja-JP.json new file mode 100644 index 00000000..770f6f07 --- /dev/null +++ b/src/lang/ja-JP.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "アクセスコード", + "label.actions": "アクション", + "label.activity-log": "アクティビティログ", + "label.add": "追加", + "label.add-description": "説明を追加", + "label.add-website": "Webサイトの追加", + "label.admin": "管理者", + "label.after": "直後", + "label.all": "すべて", + "label.all-time": "すべての時間帯", + "label.analytics": "アナリティクス", + "label.average": "平均", + "label.average-visit-time": "平均滞在時間", + "label.back": "戻る", + "label.before": "直前", + "label.bounce-rate": "直帰率", + "label.breakdown": "故障", + "label.browser": "ブラウザ", + "label.browsers": "ブラウザ", + "label.cancel": "キャンセル", + "label.change-password": "パスワードの変更", + "label.cities": "都市", + "label.city": "都市", + "label.clear-all": "すべてクリア", + "label.confirm": "確認", + "label.confirm-password": "パスワード(確認)", + "label.contains": "コンテンツ", + "label.continue": "続ける", + "label.countries": "国名", + "label.country": "国", + "label.create-report": "レポートの作成", + "label.create-team": "チームの作成", + "label.create-user": "ユーザーの作成", + "label.created": "作成されました", + "label.current-password": "現在のパスワード", + "label.custom-range": "範囲指定", + "label.dashboard": "ダッシュボード", + "label.data": "データ", + "label.date": "日付", + "label.date-range": "期間", + "label.day": "日", + "label.default-date-range": "デフォルトの期間", + "label.delete": "削除", + "label.delete-team": "チームの削除", + "label.delete-user": "ユーザーの削除", + "label.delete-website": "Webサイトの削除", + "label.description": "説明", + "label.desktop": "デスクトップ", + "label.details": "詳細情報", + "label.device": "デバイス", + "label.devices": "デバイス", + "label.dismiss": "却下", + "label.does-not-contain": "を含まない", + "label.domain": "ドメイン", + "label.dropoff": "切り捨て", + "label.edit": "編集", + "label.edit-dashboard": "ダッシュボードの編集", + "label.enable-share-url": "共有URLを有効にする", + "label.event": "イベント", + "label.event-data": "イベントデータ", + "label.events": "イベント", + "label.false": "偽", + "label.field": "フィールド", + "label.fields": "フィールド", + "label.filter-combined": "統合", + "label.filter-raw": "RAW", + "label.filters": "フィルター", + "label.funnel": "分析", + "label.greater-than": "超過", + "label.greater-than-equals": "以上", + "label.insights": "見通し", + "label.is": "に等しい", + "label.is-not": "に等しくない", + "label.is-not-set": "未設定", + "label.is-set": "設定済み", + "label.join": "参加", + "label.join-team": "チームに参加", + "label.language": "言語", + "label.languages": "言語", + "label.laptop": "ノートPC", + "label.last-days": "過去{x}日間", + "label.last-hours": "過去{x}時間", + "label.leave": "離脱", + "label.leave-team": "チームを離脱", + "label.less-than": "未満", + "label.less-than-equals": "以下", + "label.login": "ログイン", + "label.logout": "ログアウト", + "label.max": "最大", + "label.members": "メンバー", + "label.min": "最小", + "label.mobile": "携帯電話", + "label.more": "もっと見る", + "label.my-websites": "マイWebサイト", + "label.name": "名前", + "label.new-password": "新しいパスワード", + "label.none": "なし", + "label.os": "OS", + "label.overview": "概要", + "label.owner": "所有者", + "label.page-of": "ページ {current}/{total}", + "label.page-views": "閲覧数", + "label.pageTitle": "ページタイトル", + "label.pages": "ページ", + "label.password": "パスワード", + "label.powered-by": "Powered by {name}", + "label.profile": "プロフィール", + "label.queries": "クエリ", + "label.query": "クエリ", + "label.query-parameters": "クエリパラメーター", + "label.realtime": "リアルタイム", + "label.referrer": "リファラー", + "label.referrers": "リファラー", + "label.refresh": "更新", + "label.regenerate": "再生成", + "label.region": "地域", + "label.regions": "地域", + "label.remove": "削除", + "label.reports": "レポート", + "label.required": "必須", + "label.reset": "リセット", + "label.reset-website": "Webサイトをリセットする", + "label.retention": "保持", + "label.role": "ロール", + "label.run-query": "クエリ実行", + "label.save": "保存", + "label.screens": "画面サイズ", + "label.select-date": "日付を選択", + "label.select-website": "Webサイトを選択", + "label.sessions": "セッション", + "label.settings": "設定", + "label.share-url": "共有URL", + "label.single-day": "一日", + "label.sum": "合計", + "label.tablet": "タブレット", + "label.team": "チーム", + "label.team-guest": "チームゲスト", + "label.team-id": "チームID", + "label.team-member": "チームメンバー", + "label.team-name": "チーム名", + "label.team-owner": "チーム所有者", + "label.team-websites": "チームのWebサイト", + "label.teams": "チーム", + "label.theme": "テーマ", + "label.this-month": "今月", + "label.this-week": "今週", + "label.this-year": "今年", + "label.timezone": "タイムゾーン", + "label.title": "タイトル", + "label.today": "今日", + "label.toggle-charts": "グラフを切り替える", + "label.total": "累計", + "label.total-records": "総記録数", + "label.tracking-code": "トラッキングコード", + "label.true": "真", + "label.type": "種別", + "label.unique": "ユニーク", + "label.unique-visitors": "ユニーク訪問者数", + "label.unknown": "不明", + "label.untitled": "無題", + "label.url": "URL", + "label.urls": "URL", + "label.user": "ユーザー", + "label.username": "ユーザー名", + "label.users": "ユーザー", + "label.value": "値", + "label.view": "表示", + "label.view-details": "詳細を表示", + "label.view-only": "表示のみ", + "label.views": "表示", + "label.visitors": "訪問者", + "label.website": "Webサイト", + "label.website-id": "WebサイトID", + "label.websites": "Webサイト", + "label.window": "ウィンドウ", + "label.yesterday": "昨日", + "message.active-users": "{x} {x, plural, one {アクティブな訪問者} other {アクティブな訪問者}}", + "message.confirm-delete": "{target}を削除してもよろしいですか?", + "message.confirm-leave": "{target}から離脱してもよろしいですか?", + "message.confirm-reset": "{target}をリセットしてもよろしいですか?", + "message.delete-account": "このアカウントを削除するには、下のフォームに「{confirmation}」と入力してください。", + "message.delete-website": "このWebサイトを削除するには、下のフォームに「{confirmation}」と入力してください。", + "message.delete-website-warning": "Webサイトのデータがすべて削除されます。", + "message.error": "未知のエラーが発生しました。", + "message.event-log": "{url}の{event}", + "message.go-to-settings": "設定に移動する", + "message.incorrect-username-password": "ユーザー名またはパスワードが間違っています。", + "message.invalid-domain": "無効なドメインです。http/httpsを含めないでください。", + "message.min-password-length": "最小文字数は{n}文字です", + "message.new-version-available": "Umamiの新しいバージョン{version}が利用可能です!", + "message.no-data-available": "データがありません。", + "message.no-event-data": "イベントデータがありません。", + "message.no-match-password": "パスワードが一致しません。", + "message.no-results-found": "結果が見つかりません。", + "message.no-team-websites": "このチームにはWebサイトがありません。", + "message.no-teams": "チームを作成していません。", + "message.no-users": "ユーザーが存在しません。", + "message.no-websites-configured": "Webサイトが設定されていません。", + "message.page-not-found": "ページが見つかりません", + "message.reset-website": "このWebサイトをリセットするには、下のフォームに「{confirmation}」と入力してください。", + "message.reset-website-warning": "このWebサイトの統計情報はすべて削除されますが、設定はそのまま残ります。", + "message.saved": "保存されました。", + "message.share-url": "あなたのWebサイトの統計情報は次のURLで公開されています:", + "message.team-already-member": "あなたはすでにチームのメンバーです。", + "message.team-not-found": "チームが見つかりません。", + "message.team-websites-info": "Webサイトはチーム内の誰でも見ることができます。", + "message.tracking-code": "このWebサイトの統計情報を追跡するには、HTMLの...セクションに以下のコードを記述します。", + "message.user-deleted": "ユーザーが削除されました。", + "message.visitor-log": "{os}({device})で{browser}を使用している{country}からの訪問者" +} diff --git a/lang/km-KH.json b/src/lang/km-KH.json similarity index 73% rename from lang/km-KH.json rename to src/lang/km-KH.json index 4eec564f..58f7926f 100644 --- a/lang/km-KH.json +++ b/src/lang/km-KH.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "សកម្មភាព", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "បន្ថែមគេហទំព័រ", "label.admin": "អ្នកគ្រប់គ្រង", + "label.after": "After", "label.all": "ទាំងអស់", "label.all-time": "គ្រប់ពេល", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "មើលជាមធ្យម", "label.back": "ថយក្រោយ", + "label.before": "Before", "label.bounce-rate": "ចំនួនវិលត្រឡប់", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "កម្មវិធី", "label.cancel": "បោះបង់", "label.change-password": "ផ្លាស់ប្តូរពាក្យសម្ងាត់", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "បញ្ជាក់ពាក្យសម្ងាត់", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "ប្រទេស", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "កំណត់ដោយខ្លួនឯង", "label.dashboard": "ផ្ទាំងគ្រប់គ្រង", "label.data": "Data", + "label.date": "Date", "label.date-range": "ចន្លោះកាលបរិច្ឆេទ", + "label.day": "Day", "label.default-date-range": "ចន្លោះកាលបរិច្ឆេទស្រាប់", "label.delete": "លុប", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "លុបគេហទំព័រ", + "label.description": "Description", "label.desktop": "កុំព្យូទ័រលើតុ", "label.details": "Details", + "label.device": "Device", "label.devices": "ឧបករណ៍", "label.dismiss": "បដិសេធ", + "label.does-not-contain": "Does not contain", "label.domain": "ឈ្មោះគេហទំព័រ", + "label.dropoff": "Dropoff", "label.edit": "កែប្រែ", "label.edit-dashboard": "កែផ្ទាំងគ្រប់គ្រង", "label.enable-share-url": "បើកការចែករំលែក URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "ព្រឹត្តិការណ៍", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "រួមបញ្ចូលគ្នា", "label.filter-raw": "ដើម", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "ភាសា", @@ -52,46 +83,64 @@ "label.last-hours": "{x} ម៉ោងមុន", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Login", "label.logout": "ចេញ", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "ទូរស័ព្ទចល័ត", "label.more": "បន្ថែម", + "label.my-websites": "My websites", "label.name": "ឈ្មោះ", "label.new-password": "ពាក្យសម្ងាត់​ថ្មី", "label.none": "មិនមាន", - "label.operating-systems": "ប្រព័ន្ធប្រតិបត្តិការ", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "ម្ចាស់", + "label.page-of": "Page {current} of {total}", "label.page-views": "អ្នកមើលទំព័រ", + "label.pageTitle": "Page title", "label.pages": "ទំព័រ", "label.password": "ពាក្យសម្ងាត់​", "label.powered-by": "ដំណើរការដោយ {name}", "label.profile": "ប្រវត្តិរូប", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "ប៉ារ៉ាម៉ែត្រ Query", "label.realtime": "ឥលូវនេះ", + "label.referrer": "Referrer", "label.referrers": "អ្នកណែនាំ", "label.refresh": "ផ្ទុកឡើងវិញ", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "ទាមទារ", "label.reset": "កំណត់ឡើងវិញ", "label.reset-website": "កំណត់ស្ថិតិឡើងវិញ", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "រក្សាទុក", "label.screens": "ប្រភេទឧបករណ៍", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "ការកំណត់", "label.share-url": "ចែករំលែក URL", "label.single-day": "ថ្ងៃតែមួយ", + "label.sum": "Sum", "label.tablet": "ថេប្លេត", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "រូបរាង", "label.this-month": "ខែនេះ", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "ថ្ងៃនេះ", "label.toggle-charts": "បិទ/បើកតារាង", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "លេខកូដតាមដាន", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "អ្នកចូលមើលម្នាក់ៗ", "label.unknown": "មិនស្គាល់", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "ឈ្មោះ​អ្នកប្រើប្រាស់", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "មើលព័ត៌មានលម្អិត", + "label.view-only": "View only", "label.views": "អ្នកចូលមើល", "label.visitors": "អ្នកទស្សនា", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "គេហទំព័រ", + "label.window": "Window", "label.yesterday": "ម្សិលមិញ", "message.active-users": "មានអ្នកមើល {x} នាក់ ឥលូវនេះ", "message.confirm-delete": "តើអ្នកប្រាកដថាចង់លុប {target} ទេ?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "តើអ្នកប្រាកដថាចង់កំណត់ស្ថិតិរបស់ {target} ឡើងវិញទេ?", - "message.delete-website": "លុបគេហទំព័រ", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "ទិន្នន័យដែលពាក់ព័ន្ធទាំងអស់នឹងត្រូវបានលុបផងដែរ។", "message.error": "មាន​អ្វីមួយ​មិន​ប្រក្រតី។", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "ឈ្មោះអ្នកប្រើ/ពាក្យសម្ងាត់មិនត្រឹមត្រូវ។", "message.invalid-domain": "ឈ្មោះគេហទំព័រមិន​ត្រឹមត្រូវ", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "មិនមានទិន្នន័យទេ។", + "message.no-event-data": "No event data is available.", "message.no-match-password": "ពាក្យសម្ងាត់មិនត្រូវគ្នាទេ", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "អ្នកមិនទាន់បានដាក់គេហទំព័រណាមួយចូលទេ។", "message.page-not-found": "រកមិនឃើញទំព័រ។", - "message.reset-website": "កំណត់ស្ថិតិឡើងវិញ", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "ស្ថិតិទាំងអស់សម្រាប់គេហទំព័រនេះនឹងត្រូវបានលុប ប៉ុន្តែកូដតាមដានរបស់អ្នកនឹងនៅដដែល។", "message.saved": "រក្សាទុកដោយជោគជ័យ។", "message.share-url": "នេះគឺជា URL ដែលបានចែករំលែកជាសាធារណៈសម្រាប់ {target}។", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "លេខកូដតាមដាន", "message.user-deleted": "User deleted.", - "message.visitor-log": "អ្នកមើលពីប្រទេស {country} ប្រើប្រាស់កម្មវិធី {browser} លើឧបករណ៍ {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "អ្នកមិនទាន់បានដាក់គេហទំព័រណាមួយចូលទេ។", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "អ្នកមើលពីប្រទេស {country} ប្រើប្រាស់កម្មវិធី {browser} លើឧបករណ៍ {os} {device}" } diff --git a/lang/ko-KR.json b/src/lang/ko-KR.json similarity index 67% rename from lang/ko-KR.json rename to src/lang/ko-KR.json index 633552a7..767e8e22 100644 --- a/lang/ko-KR.json +++ b/src/lang/ko-KR.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "액션", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "웹사이트 추가", "label.admin": "관리자", + "label.after": "After", "label.all": "전체", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "평균 방문 시간", "label.back": "뒤로", + "label.before": "Before", "label.bounce-rate": "이탈률", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "브라우저", "label.cancel": "취소", "label.change-password": "비밀번호 변경", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "비밀번호 확인", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "국가", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "범위 지정", "label.dashboard": "대시보드", "label.data": "Data", + "label.date": "Date", "label.date-range": "날짜 범위", + "label.day": "Day", "label.default-date-range": "기본 날짜 범위", "label.delete": "삭제", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "웹사이트 삭제", + "label.description": "Description", "label.desktop": "데스크탑", "label.details": "Details", + "label.device": "Device", "label.devices": "기기", "label.dismiss": "무시하기", + "label.does-not-contain": "Does not contain", "label.domain": "도메인", + "label.dropoff": "Dropoff", "label.edit": "편집", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "URL 공유 활성화", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "이벤트", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "합쳐서 보기", "label.filter-raw": "전체 보기", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "최근 {x} 시간", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "로그인", "label.logout": "로그아웃", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "모바일", "label.more": "더 보기", + "label.my-websites": "My websites", "label.name": "이름", "label.new-password": "새 비밀번호", "label.none": "None", - "label.operating-systems": "운영체제", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "페이지 뷰(PV)", + "label.pageTitle": "Page title", "label.pages": "페이지", "label.password": "비밀번호", "label.powered-by": "이 시스템은 {name}에서 구동되고 있습니다.", "label.profile": "프로필", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "실시간", + "label.referrer": "Referrer", "label.referrers": "리퍼러", "label.refresh": "새로고침", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "필수", "label.reset": "리셋", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "저장", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "설정", "label.share-url": "공유 URL", "label.single-day": "하루", + "label.sum": "Sum", "label.tablet": "태블릿", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "이번 달", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "오늘", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "추적 코드", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "순방문자(UV)", "label.unknown": "알 수 없음", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "사용자명", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "상세보기", + "label.view-only": "View only", "label.views": "조회수", "label.visitors": "방문객", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "웹사이트", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x}명의 사용자가 보는 중입니다.", "message.confirm-delete": "{target}을(를) 삭제하시겠습니까?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "웹사이트 삭제", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "관련된 모든 데이터도 삭제됩니다.", "message.error": "오류가 발생하였습니다.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "사용자 이름/비밀번호가 잘못되었습니다..", "message.invalid-domain": "잘못된 도메인", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "사용 가능한 데이터가 없습니다.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "비밀번호가 일치하지 않음", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "구성된 웹 사이트가 없습니다.", "message.page-not-found": "페이지를 찾을 수 없습니다.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "성공적으로 저장되었습니다.", "message.share-url": "이것은 {target}의 공개적으로 공유된 URL입니다.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "추적 코드", "message.user-deleted": "User deleted.", - "message.visitor-log": "{os} {device}에서 {browser}을(를) 사용하는 {country}의 방문자", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "구성된 웹 사이트가 없습니다.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "{os} {device}에서 {browser}을(를) 사용하는 {country}의 방문자" } diff --git a/lang/lt-LT.json b/src/lang/lt-LT.json similarity index 68% rename from lang/lt-LT.json rename to src/lang/lt-LT.json index 768c32dd..c8161f1d 100644 --- a/lang/lt-LT.json +++ b/src/lang/lt-LT.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Veiksmai", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Pridėti svetainę", "label.admin": "Administratorius", + "label.after": "After", "label.all": "Visi", "label.all-time": "Visas laikotarpis", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Vidutinė vizito trukmė", "label.back": "Atgal", + "label.before": "Before", "label.bounce-rate": "Atmetimo rodiklis", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Naršyklės", "label.cancel": "Atšaukti", "label.change-password": "Pakeisti slaptažodį", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Patvirtinti slaptažodį", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Šalys", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Pasirinktinis intervalas", "label.dashboard": "Švieslentė", "label.data": "Data", + "label.date": "Date", "label.date-range": "Laikotarpis", + "label.day": "Day", "label.default-date-range": "Numatytasis laikotarpis", "label.delete": "Ištrinti", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Ištrinti svetainę", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Įrenginiai", "label.dismiss": "Gerai", + "label.does-not-contain": "Does not contain", "label.domain": "Domenas", + "label.dropoff": "Dropoff", "label.edit": "Redaguoti", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Įjungti bendrinimą su nuoroda", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Įvykiai", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Kombinuoti", "label.filter-raw": "Neapdoroti", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "{x, plural, =0 {Paskutinės # valandų} zero {Paskutinės # valandų} one {Paskutinė # valanda} other {Paskutinės # valandos}}", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Prisijungti", "label.logout": "Atsijungti", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobilusis", "label.more": "Daugiau", + "label.my-websites": "My websites", "label.name": "Pavadinimas", "label.new-password": "Naujas slaptažodis", "label.none": "None", - "label.operating-systems": "Operacinės sistemos", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Savininkas", + "label.page-of": "Page {current} of {total}", "label.page-views": "Puslapių peržiūros", + "label.pageTitle": "Page title", "label.pages": "Puslapiai", "label.password": "Slaptažodis", "label.powered-by": "Powered by {name}", "label.profile": "Profilis", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Realiuoju laiku", + "label.referrer": "Referrer", "label.referrers": "Referrers", "label.refresh": "Atnaujinti", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Reikalinga", "label.reset": "Atstatyti", "label.reset-website": "Atstatyti statistikos duomenis", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Išsaugoti", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Nustatymai", "label.share-url": "Pasidalinti nuoroda", "label.single-day": "Viena diena", + "label.sum": "Sum", "label.tablet": "Planšetė", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Šis mėnuo", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Šiandien", "label.toggle-charts": "Rodyti / slėpti grafikus", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Sekimo kodas", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Unikalūs lankytojai", "label.unknown": "Nežinoma", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Vartotojo vardas", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Peržiūrėti detaliau", + "label.view-only": "View only", "label.views": "Peržiūros", "label.visitors": "Lankytojai", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Svetainės", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x, plural, =0 {# aktyvių vartotojų} zero {# aktyvių vartotojų} one {# aktyvus vartotojas} other {# aktyvūs vartotojai}}", "message.confirm-delete": "Ar esate tikri, jog norite ištrinti svetainę {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are esate tikri, jog norite atstatyti svetainės {target} statistikos duomenis?", - "message.delete-website": "Ištrinti svetainę", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Visi susiję duomenys taip pat bus ištrinti.", "message.error": "Kažkas įvyko ne taip.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Neteisingas vartotojo vardas/slaptažodis.", "message.invalid-domain": "Klaidingas domenas", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Nėra jokių duomenų.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Slaptažodžiai nesutampa", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Jūs nesate susikonfiguravę jokių svetainių.", "message.page-not-found": "Puslapis nerastas.", - "message.reset-website": "Atstatyti statistikos duomenis", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Visi šios svetainės statistikos duomenys bus ištrinti, bet sekimo kodas išliks nepaliestas.", "message.saved": "Sėkmingai išsaugota.", "message.share-url": "Tai yra viešai prieinama {target} nuoroda (URL).", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Sekimo kodas", "message.user-deleted": "User deleted.", - "message.visitor-log": "Lankytojas iš {country}, naudojantis {browser} sistemoje {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Jūs nesate susikonfiguravę jokių svetainių.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Lankytojas iš {country}, naudojantis {browser} sistemoje {os} {device}" } diff --git a/src/lang/mn-MN.json b/src/lang/mn-MN.json new file mode 100644 index 00000000..1478c079 --- /dev/null +++ b/src/lang/mn-MN.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Хандалтын код", + "label.actions": "Үйлдлүүд", + "label.activity-log": "Үйл ажиллагааны бүртгэл", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "Веб нэмэх", + "label.admin": "Админ", + "label.after": "After", + "label.all": "Бүх", + "label.all-time": "Бүх цаг үеийн", + "label.analytics": "Analytics", + "label.average": "Average", + "label.average-visit-time": "Зочилсон дундаж хугацаа", + "label.back": "Буцах", + "label.before": "Before", + "label.bounce-rate": "Нэг хуудас үзээд гарсан", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Хөтөч", + "label.cancel": "Цуцлах", + "label.change-password": "Нууц үг солих", + "label.cities": "Хотууд", + "label.city": "City", + "label.clear-all": "Бүгдийг арилгах", + "label.confirm": "Батлах", + "label.confirm-password": "Шинэ нууц үгээ давтах", + "label.contains": "Contains", + "label.continue": "Үргэлжлүүлэх", + "label.countries": "Улс", + "label.country": "Country", + "label.create-report": "Create report", + "label.create-team": "Баг үүсгэх", + "label.create-user": "Хэрэглэгч үүсгэх", + "label.created": "Үүсгэсэн", + "label.current-password": "Ашиглаж буй нууц үг", + "label.custom-range": "Дурын хугацаа", + "label.dashboard": "Хянах самбар", + "label.data": "Өгөгдөл", + "label.date": "Date", + "label.date-range": "Хугацааны муж", + "label.day": "Day", + "label.default-date-range": "Өгөгдмөл хугацааны муж", + "label.delete": "Устгах", + "label.delete-team": "Баг устгах", + "label.delete-user": "Хэрэглэгч устгах", + "label.delete-website": "Веб устгах", + "label.description": "Description", + "label.desktop": "Суурин компьютер", + "label.details": "Мэдээлэл", + "label.device": "Device", + "label.devices": "Төхөөрөмж", + "label.dismiss": "Үл хэргэсэх", + "label.does-not-contain": "Does not contain", + "label.domain": "Домэйн", + "label.dropoff": "Dropoff", + "label.edit": "Засах", + "label.edit-dashboard": "Хянах самбар засах", + "label.enable-share-url": "Хуваалцах холбоос идэвхжүүлэх", + "label.event": "Event", + "label.event-data": "Event data", + "label.events": "Үйлдэл", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", + "label.filter-combined": "Нэгтгэсэн", + "label.filter-raw": "Түүхий", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Нэгдэх", + "label.join-team": "Багт нэгдэх", + "label.language": "Хэл", + "label.languages": "Хэл", + "label.laptop": "Зөөврийн компьютер", + "label.last-days": "Сүүлийн {x} хоног", + "label.last-hours": "Сүүлийн {x} цаг", + "label.leave": "Гарах", + "label.leave-team": "Багаас гарах", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", + "label.login": "Нэвтрэх", + "label.logout": "Гарах", + "label.max": "Max", + "label.members": "Гишүүд", + "label.min": "Min", + "label.mobile": "Утас", + "label.more": "Цааш", + "label.my-websites": "My websites", + "label.name": "Нэр", + "label.new-password": "Шинэ нууц үг", + "label.none": "Байхгүй", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "Эзэмшигч", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Хуудас үзсэн", + "label.pageTitle": "Page title", + "label.pages": "Хуудас", + "label.password": "Нууц үг", + "label.powered-by": "{name} дээр суурилсан", + "label.profile": "Бүртгэл", + "label.queries": "Query-нүүд", + "label.query": "Query", + "label.query-parameters": "Query параметр", + "label.realtime": "Яг одоо", + "label.referrer": "Referrer", + "label.referrers": "Чиглүүлэгч", + "label.refresh": "Сэргээх", + "label.regenerate": "Дахин үүсгэх", + "label.region": "Region", + "label.regions": "Бүсүүд", + "label.remove": "Устгах", + "label.reports": "Reports", + "label.required": "Шаардлагатай", + "label.reset": "Дахин эхлүүлэх", + "label.reset-website": "Тоон үзүүлэлтийг дахин эхлүүлэх", + "label.retention": "Retention", + "label.role": "Эрх", + "label.run-query": "Run query", + "label.save": "Хадгалах", + "label.screens": "Дэлгэц", + "label.select-date": "Select date", + "label.select-website": "Веб сонгох", + "label.sessions": "Sessions", + "label.settings": "Тохиргоо", + "label.share-url": "Хуваалцах холбоос", + "label.single-day": "Нэг өдөр", + "label.sum": "Sum", + "label.tablet": "Таблет", + "label.team": "Баг", + "label.team-guest": "Багийн зочин", + "label.team-id": "Багийн ID", + "label.team-member": "Багийн гишүүн", + "label.team-name": "Team name", + "label.team-owner": "Багийн эзэмшигч", + "label.team-websites": "Team websites", + "label.teams": "Багууд", + "label.theme": "Загвар", + "label.this-month": "Энэ сар", + "label.this-week": "Энэ долоо хоног", + "label.this-year": "Энэ жил", + "label.timezone": "Цагийн бүс", + "label.title": "Гарчиг", + "label.today": "Өнөөдөр", + "label.toggle-charts": "Графикийг харуулах/нуух", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Мөрдөх код", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", + "label.unique-visitors": "Зочин", + "label.unknown": "Тодорхойгүй", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "Хэрэглэгч", + "label.username": "Хэрэглэгчийн нэр", + "label.users": "Хэрэглэгчид", + "label.value": "Value", + "label.view": "Харах", + "label.view-details": "Дэлгэрүүлж харах", + "label.view-only": "View only", + "label.views": "Үзсэн", + "label.visitors": "Зочин", + "label.website": "Website", + "label.website-id": "Вебийн ID", + "label.websites": "Вебүүд", + "label.window": "Window", + "label.yesterday": "Өчигдөр", + "message.active-users": "одоо {x} {x, plural, one {зочин} other {зочин}} байна", + "message.confirm-delete": "Та {target}-г устгахдаа итгэлтэй байна уу?", + "message.confirm-leave": "Та {target}-с гарахдаа итгэлтэй байна уу?", + "message.confirm-reset": "Та {target}-н тоон үзүүлэлтүүдийг устгахдаа итгэлтэй байна уу?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", + "message.delete-website-warning": "Энэ вебтэй холбоотой бүх өгөгдөл устах болно.", + "message.error": "Ямар нэг зүйл буруу боллоо.", + "message.event-log": "{url}-д {event}", + "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.no-data-available": "Өгөгдөл алга.", + "message.no-event-data": "No event data is available.", + "message.no-match-password": "Нууц үг тохирохгүй байна.", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "Энэ багт ямар ч веб алга.", + "message.no-teams": "Та ямар ч баг үүсгээгүй байна.", + "message.no-users": "Хэрэглэгч байхгүй байна.", + "message.no-websites-configured": "Та ямар нэгэн веб тохируулаагүй байна.", + "message.page-not-found": "Хуудас олдсонгүй.", + "message.reset-website": "Тоон үзүүлэлийг дахин эхлүүлэхийн тулд доорх хэсэгт {confirmation} гэж бичиж, баталгаажуулна уу.", + "message.reset-website-warning": "Энэ вебийн бүх тоон үзүүлэлтүүдийг устгах болно. Гэхдээ мөрдөх код хэвэндээ үлдэнэ.", + "message.saved": "Хадгалсан.", + "message.share-url": "Таны вебийн тоон үзүүлэлтүүд доорх URL дээр нийтэд харагдах болно:", + "message.team-already-member": "Та аль хэдийн энэ багийн гишүүн болсон байна.", + "message.team-not-found": "Баг олдсонгүй.", + "message.team-websites-info": "Вебийг багийн бүх гишүүд үзэж болно.", + "message.tracking-code": "Энэ вебийн хандалтуудыг мөрдөхийн тулд доорх кодыг HTML-нхээ ... хэсэгт байрлуулна уу.", + "message.user-deleted": "Хэрэглэгч устсан.", + "message.visitor-log": "{country} улсаас {os} {device} дээр {browser} хөтөч ашиглан орсон" +} diff --git a/lang/ms-MY.json b/src/lang/ms-MY.json similarity index 66% rename from lang/ms-MY.json rename to src/lang/ms-MY.json index a9469af8..5b8769c5 100644 --- a/lang/ms-MY.json +++ b/src/lang/ms-MY.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Aksi", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Tambah laman web", "label.admin": "Pentadbir", + "label.after": "After", "label.all": "Semua", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Purata tempoh masa lawatan", "label.back": "Kembali", + "label.before": "Before", "label.bounce-rate": "Kadar lantunan", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Pelayar web", "label.cancel": "Batal", "label.change-password": "Tukar kata laluan", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Sahkan kata laluan", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Negara", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Julat khas", "label.dashboard": "Papan pemuka", "label.data": "Data", + "label.date": "Date", "label.date-range": "Julat tarikh", + "label.day": "Day", "label.default-date-range": "Julat tarikh lalai", "label.delete": "Padam", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Padam laman web", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Peranti", "label.dismiss": "Ketepikan", + "label.does-not-contain": "Does not contain", "label.domain": "Domain", + "label.dropoff": "Dropoff", "label.edit": "Edit", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Aktifkan url berkongsi", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Peristiwa", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Digabungkan", "label.filter-raw": "Mentah", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "{x} jam lepas", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Log masuk", "label.logout": "Log keluar", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Telefon bimbit", "label.more": "Lebih banyak lagi", + "label.my-websites": "My websites", "label.name": "Nama", "label.new-password": "Kata laluan baru", "label.none": "None", - "label.operating-systems": "Sistem operasi", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Paparan halaman", + "label.pageTitle": "Page title", "label.pages": "Halaman", "label.password": "Kata laluan", "label.powered-by": "Disediakan oleh {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Siaran langsung", + "label.referrer": "Referrer", "label.referrers": "Perujuk", "label.refresh": "Muat semula", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Diperlukan", "label.reset": "Tetapkan semula", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Simpan", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Tetapan", "label.share-url": "Kongsikan URL", "label.single-day": "Satu hari", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Bulan ini", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Hari ini", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Kod penjejakan", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Pelawat unik", "label.unknown": "Tidak diketahui", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Nama pengguna", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Lihat butiran", + "label.view-only": "View only", "label.views": "Lawatan", "label.visitors": "Pelawat", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Laman web", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} semasa {x, plural, one {pelawat} other {pelawat}}", "message.confirm-delete": "Pastikah anda ingin memadam {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Padam laman web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Semua data yang berkaitan juga akan dihapuskan.", "message.error": "Ada yang tidak kena.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Pengguna/kata laluan tidak betul.", "message.invalid-domain": "Domain tidak sah", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Tiada data yang boleh didapati.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Kata laluan tidak sepadan", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Anda tidak ada sebarang laman web yang telah dikonfigurasikan.", "message.page-not-found": "Halaman tidak dijumpai.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Berjaya disimpan.", "message.share-url": "Ini adalah URL berkongsi untuk {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Kod penjejakan", "message.user-deleted": "User deleted.", - "message.visitor-log": "Pelawat dari {country} mengguna {browser} pada {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Anda tidak ada sebarang laman web yang telah dikonfigurasikan.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Pelawat dari {country} mengguna {browser} pada {os} {device}" } diff --git a/src/lang/my-MM.json b/src/lang/my-MM.json new file mode 100644 index 00000000..de92b275 --- /dev/null +++ b/src/lang/my-MM.json @@ -0,0 +1,195 @@ +{ + "label.access-code": "ဝင်ခွင့်ကုဒ်", + "label.actions": "လုပ်ဆောင်ချက်များ", + "label.activity-log": "လုပ်ဆောင်ချက်စာရင်း", + "label.add": "ထပ်ထည့်မည်", + "label.add-description": "အကြောင်းအရာဖော်ပြချက် ထည့်မည်", + "label.add-website": "ဝက်ဘ်ဆိုဒ်ထည့်မည်", + "label.admin": "အက်ဒမင်", + "label.all": "အားလုံး", + "label.all-time": "အချိန်အစမှအခုထိ", + "label.analytics": "အန်နလစ်တစ်", + "label.average-visit-time": "ဝဘက်ဘ်ဆိုဒ်တွင် ပျမ်းမျှကုန်ဆုံးချိန်", + "label.back": "နောက်သို့", + "label.bounce-rate": "Bounce နှုန်း", + "label.browsers": "ဝက်ဘ်ဘရောင်ဇာများ", + "label.cancel": "မလုပ်တော့ပါ", + "label.change-password": "စကားဝှက် ပြောင်းမည်", + "label.cities": "မြို့များ", + "label.clear-all": "အားလုံးကိုဖျက်မည်", + "label.confirm": "အတည်ပြုသည်", + "label.confirm-password": "စကားဝှက်အတည်ပြုသည်", + "label.continue": "ဆက်သွားမည်", + "label.countries": "နိုင်ငံများ", + "label.create-team": "Team ပြုလုပ်မည်", + "label.create-user": "အသုံးပြုသူထည့်မည်", + "label.created": "ပြုလုပ်ပြီးသော", + "label.current-password": "လက်ရှိစကားဝှက်", + "label.custom-range": "အချိန်အပိုင်းအခြားရွေးရန်", + "label.dashboard": "ဒက်ရှ်ဘုတ်", + "label.data": "ဒေတာ", + "label.date-range": "ရက်အပိုင်းအခြား", + "label.default-date-range": "ပုံသေ ရက်အပိုင်းအခြား", + "label.delete": "ဖျက်မည်", + "label.delete-team": "Team ကိုဖျက်မည်", + "label.delete-user": "အသုံးပြုသူကိုဖျက်မည်", + "label.delete-website": "ဝက်ဘ်ဆိုဒ်ကိုဖျက်မည်", + "label.desktop": "စားပွဲတင်ကွန်ပျူတာ", + "label.details": "အသေးစိတ်", + "label.devices": "အသုံးပြုသည့် ကိရိယာများ", + "label.dismiss": "ပိတ်ပါ", + "label.domain": "ဒိုမိန်း", + "label.dropoff": "Dropoff", + "label.edit": "ပြုပြင်မည်", + "label.edit-dashboard": "ဒက်ရှ်ဘုတ်ကို ပြုပြင်မည်", + "label.enable-share-url": "ဝေငှခြင်းကိုလင့်ကို ဖွင့်မည်", + "label.event": "အဖြစ်အပျက်", + "label.event-data": "အဖြစ်အပျက် ဒေတာ", + "label.events": "အဖြစ်အပျက်များ", + "label.field": "Field အမည်", + "label.fields": "Field အမည်များ", + "label.filter-combined": "ပေါင်းစပ်ပြီး", + "label.filter-raw": "အရှိအတိုင်း", + "label.funnel": "ဖန်နယ်", + "label.insights": "အသေးစိတ်သိမြင်နိုင်ရန်", + "label.join": "ဝင်မည်", + "label.join-team": "အသင်းဝင်မည်", + "label.language": "ဘာသာစကား", + "label.languages": "ဘာသာစကားများ", + "label.laptop": "လက်တော့ပ်", + "label.last-days": "လွန်ခဲ့သော {x} ရက်က", + "label.last-hours": "လွန်ခဲ့သော {x} နာရီက", + "label.leave": "ထွက်မည်", + "label.leave-team": "အသင်းမှထွက်မည်", + "label.login": "လော့ဂ်အင်", + "label.logout": "လော့ဂ်အောက်လုပ်မည်", + "label.members": "အဖွဲ့ဝင်များ", + "label.mobile": "မိုဘိုင်း", + "label.more": "နောက်ထပ်", + "label.name": "အမည်", + "label.new-password": "စကားဝှက်အသစ်", + "label.none": "မရှိပါ", + "label.operating-systems": "ကွန်ပျူတာလည်ပတ်မှုစနစ်", + "label.owner": "ပိုင်ဆိုင်သူ", + "label.page-views": "ဝင်ရောက်ကြည့်ရှုသူ", + "label.pages": "စာမျက်နှာများ", + "label.password": "စကားဝှက်", + "label.powered-by": "{name} ထောက်ပံ့သည်", + "label.profile": "ပရိုဖိုင်း", + "label.queries": "Queries (ကွာရီများ)", + "label.query": "Query (ကွာရီ)", + "label.query-parameters": "Query parameters (ကွာရီပါရာမီတာများ)", + "label.realtime": "အချိန်နှင့်တပြေးညီ", + "label.referrers": "ရည်ညွှန်းမှုများ", + "label.refresh": "Refresh လုပ်မည်", + "label.regenerate": "ပြန်ထုတ်မည်", + "label.regions": "ဒေသများ", + "label.remove": "ဖျက်မည်", + "label.reports": "တင်ပြမှုများ", + "label.required": "လိုအပ်သည်", + "label.reset": "ပြန်စမည်", + "label.reset-website": "ဝက်ဘ်ဆိုဒ်ဒေတာကိုဖျက်မည်", + "label.role": "အခန်းကဏ္ဍ", + "label.run-query": "Query ကိုလုပ်ဆောင်မည်", + "label.save": "သိမ်းဆည်းမည်", + "label.screens": "မြင်ကွင်းများ", + "label.select-date": "ရက်ရွေးပါ", + "label.select-website": "ဝဘက်ဘ်ဆိုဒ်ရွေးပါ", + "label.sessions": "ဆက်ရှင်များ", + "label.settings": "ဆက်တင်များ", + "label.share-url": "URL ကိုရှဲမည်", + "label.single-day": "တစ်ရက်အတွင်း", + "label.tablet": "တက်ဘလက်", + "label.team": "အသင်း", + "label.team-guest": "အသင်း ဧည့်သည်", + "label.team-id": "အသင်း အိုင်ဒီ", + "label.team-member": "အသင်းဝင်", + "label.team-owner": "အသင်းကိုပိုင်ဆိုင်သူ", + "label.teams": "အသင်းများ", + "label.theme": "Theme (အပြင်အဆင်)", + "label.this-month": "ယခုလ", + "label.this-week": "ယခုအပတ်", + "label.this-year": "ယခုနှစ်", + "label.timezone": "အချိန်ဇုန်", + "label.title": "ခေါင်းစဥ်", + "label.today": "ယနေ့", + "label.toggle-charts": "ဇယားများကို အဖွင့်အပိတ်လုပ်မည်", + "label.tracking-code": "ထရက်လုပ်သည့် ကုဒ်", + "label.unique-visitors": "ဝင်ရောက်သူ (ထပ်ခြင်းမရှိ)", + "label.unknown": "မသိသော", + "label.url": "URL", + "label.urls": "URL များ", + "label.user": "အသုံးပြုသူ", + "label.username": "အသုံးပြုသူအမည်", + "label.users": "အသုံးပြုသူများ", + "label.view": "ဝင်ရောက်ကြည့်ရှုမှု", + "label.view-details": "အသေးစိတ်ကို ကြည့်ရှုမည်", + "label.view-only": "ဝင်ရောက်ကြည့်ရှုမှုများသာ", + "label.views": "ဝင်ရောက်ကြည့်ရှုမှုများ", + "label.visitors": "ဝင်ရောက်ကြည့်ရှုသူများ", + "label.website": "ဝက်ဘ်ဆိုဒ်", + "label.website-id": "ဝက်ဘ်ဆိုဒ် အိုင်ဒီ", + "label.websites": "ဝက်ဘ်ဆိုဒ်များ", + "label.window": "ဝင်းဒိုး", + "label.yesterday": "မနေ့က", + "labels.after": "ပြီးနောက်", + "labels.average": "ပျမ်းမျှ", + "labels.before": "မတိုင်မီ", + "labels.breakdown": "ခွဲခြမ်းစိတ်ဖြာမှု", + "labels.contains": "ပါဝင်သည်", + "labels.create-report": "ရီပို့လုပ်မည်", + "labels.description": "ရှင်းပြချက်", + "labels.does-not-contain": "မပါဝင်ပါ", + "labels.does-not-equal": "မတူညီပါ", + "labels.equals": "တူညီသည်", + "labels.false": "မှားသည်", + "labels.filters": "Filter များ", + "labels.greater-than": "ထက်ပို၍ကြီးသည်", + "labels.greater-than-equals": "ထက်ပို၍ကြီးသည်သို့မဟုတ်တူသည်", + "labels.less-than": "ထက်ပို၍ငယ်သည်", + "labels.less-than-equals": "ထက်ပို၍ငယ်သည်သို့မဟုတ်တူသည်", + "labels.max": "အများဆုံး", + "labels.min": "အနည်းဆုံး", + "labels.overview": "အပေါ်ယံမြင်ကွင်း", + "labels.sum": "ပေါင်းလဒ်", + "labels.total": "စုစုပေါင်း", + "labels.total-records": "မှတ်တမ်းစုစုပေါင်း", + "labels.true": "မှန်သည်", + "labels.type": "အမျိုးအစား", + "labels.unique": "Unique", + "labels.untitled": "ခေါင်းစဉ်မရှိ", + "labels.value": "တန်ဖိုး", + "message.active-users": "{x} လက်ရှိအသုံးပြုနေသူ {x, plural, one {ယောက်} other {ယောက်}}", + "message.confirm-delete": "{target} ကို ဖျက်ရန် သေချာပါသလား?", + "message.confirm-leave": "{target} ကို ထွက်ရန် သေချာပါသလား?", + "message.confirm-reset": "{target} ကို ဖျက်၍ပြန်စလုပ်ရန် သေချာပါသလား?", + "message.delete-account": "ဤအကောင့်ကိုဖျက်ရန် {confirmation} ကို ရိုက်ထည့်ပေးပါ.", + "message.delete-website": "ဤ ဝက်ဘ်ဆိုဒ်ကိုဖျက်ရန် {confirmation} ကို ရိုက်ထည့်ပေးပါ", + "message.delete-website-warning": "ဝက်ဘ်ဆိုဒ် ဒေတာအကုန် ဖျက်မည်", + "message.error": "မှားယွင်းမှုတစ်ခု ရှိသွားပါသည်", + "message.event-log": "{url} တွင် {event}", + "message.go-to-settings": "ဆက်တင်သို့ သွားရန်", + "message.incorrect-username-password": "အသုံးပြုသူအမည် သို့မဟုတ် စကားဝှက် မှားနေသည်", + "message.invalid-domain": "ဒိုမိန်း မမှန်ပါ http/https. မပါရပါ", + "message.min-password-length": "အနည်းဆုံး {n} character ရှိရမည်", + "message.no-data-available": "ဒေတာ မရှိပါ", + "message.no-event-data": "အဖြစ်အပျက်ဒေတာ မရှိပါ", + "message.no-match-password": "စကားဝှက် မှားနေသည်", + "message.no-teams": "အသင်း မပြုလုပ်ရသေးပါ", + "message.no-users": "အသုံးပြုသူ မရှိသေးပါ", + "message.page-not-found": "ဤစာမျက်နှာသည် မရှိပါ", + "message.reset-website": "ဤ ဝက်ဘ်ဆိုဒ်ဒေတာကိုဖျက်၍ ပြန်စလုပ်ရန် အောက်တွင် {confirmation} ကို ရိုက်ထည့်ပေးပါ", + "message.reset-website-warning": "ဤဝက်ဘ်ဆိုဒ်က စာရင်းအချက်အလက်များကို ဖျက်မည်၊ ဆက်တင်ဒေတာများ မပါပါ", + "message.saved": "မှတ်သားပြီး", + "message.share-url": "သင့်ဝက်ဆိုဒ်ဘ်၏ စာရင်းအချက်အလက်များကို အောက်ပါ URL တွင် ဝင်ရောက်ကြည့်ရှုနိုင်သည်", + "message.team-already-member": "ဤအသင်းတွင် ဝင်ပြီးသားဖြစ်နေသည်", + "message.team-not-found": "အသင်း မရှိပါ", + "message.tracking-code": "ဤဝက်ဘ်ဆိုဒ်၏ ဒေတာကိုကောက်ခံရန် အောက်ပါ code ကို သင်၏ HTML တွင်ထည့်ပါ", + "message.user-deleted": "အသုံးပြုသူ ဖျက်ပြီးပါပြီ", + "message.visitor-log": "{country} မှ {browser} ဖြင့် {os} {device} တွင် ဝင်ရောက်ကြည့်ရှုသူ", + "message.no-results-found": "ရလဒ်မရှိပါ", + "message.no-team-websites": "ဤအသင်းတွင် ဝက်ဘ်ဆိုက်မရှိသေးပါ", + "message.no-websites-configured": "ဝက်ဘ်ဆိုဒ်တစ်ခုမှ မထည့်ရသေးပါ", + "message.team-websites-info": "ဤဝက်ဘ်ဆိုဒ်များကို အသင်းထဲမှ လူတိုင်းဝင်ကြည့်နိုင်သည်", + "message.new-version-available": "အူမာမီ {version} အသစ်ထွက်နေပါပြီ" +} diff --git a/lang/nb-NO.json b/src/lang/nb-NO.json similarity index 66% rename from lang/nb-NO.json rename to src/lang/nb-NO.json index 4bb8c74f..654c3c79 100644 --- a/lang/nb-NO.json +++ b/src/lang/nb-NO.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Handlinger", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Legg til nettsted", "label.admin": "Administrator", + "label.after": "After", "label.all": "Alle", "label.all-time": "Noensinne", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Gjennomsnittlig besøkstid", "label.back": "Tilbake", + "label.before": "Before", "label.bounce-rate": "Avvisningsfrekvens", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Nettlesere", "label.cancel": "Avvis", "label.change-password": "Bytt passord", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Godkjenn passord", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Land", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Egendefinert utvalg", "label.dashboard": "Dashbord", "label.data": "Data", + "label.date": "Date", "label.date-range": "Datointervall", + "label.day": "Day", "label.default-date-range": "Standard datoperiode", "label.delete": "Slett", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Slett nettstedet", + "label.description": "Description", "label.desktop": "Stasjonær", "label.details": "Details", + "label.device": "Device", "label.devices": "Enheter", "label.dismiss": "Avbryt", + "label.does-not-contain": "Does not contain", "label.domain": "Domene", + "label.dropoff": "Dropoff", "label.edit": "Rediger", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Aktiver delings-URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Arrangementer", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Kombinert", "label.filter-raw": "Rå", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Språk", @@ -52,46 +83,64 @@ "label.last-hours": "Siste {x} timer", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Logg inn", "label.logout": "Logg ut", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobiltelefon", "label.more": "Mer", + "label.my-websites": "My websites", "label.name": "Navn", "label.new-password": "Nytt passord", "label.none": "None", - "label.operating-systems": "Operativsystemer", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Eier", + "label.page-of": "Page {current} of {total}", "label.page-views": "Sidevisninger", + "label.pageTitle": "Page title", "label.pages": "Sider", "label.password": "Passord", "label.powered-by": "Drevet av {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Sanntid", + "label.referrer": "Referrer", "label.referrers": "Referanser", "label.refresh": "Oppdater", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Påkrevd", "label.reset": "Nullstill", "label.reset-website": "Nullstill statistikk", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Lagre", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Innstillinger", "label.share-url": "Del URL", "label.single-day": "Enkelt dag", + "label.sum": "Sum", "label.tablet": "Nettbrett", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Denne måneden", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "I dag", "label.toggle-charts": "Veksle grafer", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Sporingskode", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Unike besøkende", "label.unknown": "Ukjent", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Brukernavn", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Vis detaljer", + "label.view-only": "View only", "label.views": "Visninger", "label.visitors": "Besøkende", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Nettsteder", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} {x, plural, one {besøkende} other {besøkende}} nå", "message.confirm-delete": "Er du sikker på at du vil slette {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Er du sikker på at du vil nullstille {target}'s statistikk?", - "message.delete-website": "Slett nettstedet", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Alle tilknyttede data slettes også.", "message.error": "Noe gikk galt.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Ugyldig brukernavn/passord.", "message.invalid-domain": "Ugyldig domene", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Ingen data tilgjengelig.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Passordene er ikke like", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Du har ikke satt opp noen nettsteder.", "message.page-not-found": "Side ikke funnet.", - "message.reset-website": "Nullstill statistikk", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistikk for denne nettsiden vil bli slettet, men sporingskoden din vil forbli uberørt.", "message.saved": "Lagret!", "message.share-url": "Dette er den offentlige delings-URL-en for {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Sporingskode", "message.user-deleted": "User deleted.", - "message.visitor-log": "Besøkende fra {country} med {browser} på {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Du har ikke satt opp noen nettsteder.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Besøkende fra {country} med {browser} på {os} {device}" } diff --git a/src/lang/nl-NL.json b/src/lang/nl-NL.json new file mode 100644 index 00000000..ad30cf36 --- /dev/null +++ b/src/lang/nl-NL.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Toegangscode", + "label.actions": "Acties", + "label.activity-log": "Activiteiten logboek", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "Website koppelen", + "label.admin": "Beheerder", + "label.after": "After", + "label.all": "Alles", + "label.all-time": "Onbeperkt", + "label.analytics": "Analytics", + "label.average": "Average", + "label.average-visit-time": "Gemiddelde bezoektijd", + "label.back": "Terug", + "label.before": "Before", + "label.bounce-rate": "Bouncepercentage", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Browsers", + "label.cancel": "Annuleren", + "label.change-password": "Wachtwoord wijzigen", + "label.cities": "Steden", + "label.city": "City", + "label.clear-all": "Filters wissen", + "label.confirm": "Bevestigen", + "label.confirm-password": "Wachtwoord bevestigen", + "label.contains": "Contains", + "label.continue": "Doorgaan", + "label.countries": "Landen", + "label.country": "Country", + "label.create-report": "Create report", + "label.create-team": "Team aanmaken", + "label.create-user": "Gebruiker maken", + "label.created": "Gemaakt", + "label.current-password": "Huidig wachtwoord", + "label.custom-range": "Aangepast bereik", + "label.dashboard": "Overzicht", + "label.data": "Gegevens", + "label.date": "Date", + "label.date-range": "Datumbereik", + "label.day": "Day", + "label.default-date-range": "Standaard bereik", + "label.delete": "Verwijderen", + "label.delete-team": "Team verwijderen", + "label.delete-user": "Verwijder gebruiker", + "label.delete-website": "Website verwijderen", + "label.description": "Description", + "label.desktop": "Computer", + "label.details": "Informatie", + "label.device": "Device", + "label.devices": "Apparaten", + "label.dismiss": "Negeren", + "label.does-not-contain": "Does not contain", + "label.domain": "Domein", + "label.dropoff": "Dropoff", + "label.edit": "Bewerken", + "label.edit-dashboard": "Dashboard aanpassen", + "label.enable-share-url": "Sta delen via openbare URL toe", + "label.event": "Event", + "label.event-data": "Event data", + "label.events": "Gebeurtenissen", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", + "label.filter-combined": "Gecombineerd", + "label.filter-raw": "Ruw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Lid worden", + "label.join-team": "Word lid van een team", + "label.language": "Taal", + "label.languages": "Talen", + "label.laptop": "Laptop", + "label.last-days": "Laatste {x} dagen", + "label.last-hours": "Laatste {x} uur", + "label.leave": "Verlaten", + "label.leave-team": "Verlaat team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", + "label.login": "Inloggen", + "label.logout": "Uitloggen", + "label.max": "Max", + "label.members": "Gebruikers", + "label.min": "Min", + "label.mobile": "Mobiel", + "label.more": "Toon meer", + "label.my-websites": "My websites", + "label.name": "Naam", + "label.new-password": "Nieuw wachtwoord", + "label.none": "Geen", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "Eigenaar", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Paginaweergaven", + "label.pageTitle": "Page title", + "label.pages": "Pagina's", + "label.password": "Wachtwoord", + "label.powered-by": "mogelijk gemaakt door {name}", + "label.profile": "Profiel", + "label.queries": "Parameters", + "label.query": "Query", + "label.query-parameters": "URL-parameters", + "label.realtime": "Actueel", + "label.referrer": "Referrer", + "label.referrers": "Verwijzers", + "label.refresh": "Vernieuwen", + "label.regenerate": "Opnieuw genereren", + "label.region": "Region", + "label.regions": "Regio's", + "label.remove": "Verwijderen", + "label.reports": "Reports", + "label.required": "Verplicht", + "label.reset": "Opnieuw instellen", + "label.reset-website": "Statistieken opnieuw instellen", + "label.retention": "Retention", + "label.role": "Gebruikersrol", + "label.run-query": "Run query", + "label.save": "Opslaan", + "label.screens": "Schermen", + "label.select-date": "Select date", + "label.select-website": "Website selecteren", + "label.sessions": "Sessies", + "label.settings": "Instellingen", + "label.share-url": "URL delen", + "label.single-day": "Enkele dag", + "label.sum": "Sum", + "label.tablet": "Tablet", + "label.team": "Team", + "label.team-guest": "Team gast", + "label.team-id": "Team ID", + "label.team-member": "Teamlid", + "label.team-name": "Team name", + "label.team-owner": "Teameigenaar", + "label.team-websites": "Team websites", + "label.teams": "Teams", + "label.theme": "Thema", + "label.this-month": "Deze maand", + "label.this-week": "Deze week", + "label.this-year": "Dit jaar", + "label.timezone": "Tijdzone", + "label.title": "Titel", + "label.today": "Vandaag", + "label.toggle-charts": "Grafieken tonen/verbergen", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Volgcode", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", + "label.unique-visitors": "Unieke bezoekers", + "label.unknown": "Onbekend", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "Gebruiker", + "label.username": "Gebruikersnaam", + "label.users": "Gebruikers", + "label.value": "Value", + "label.view": "Weergave", + "label.view-details": "Meer details", + "label.view-only": "View only", + "label.views": "Weergaven", + "label.visitors": "Bezoekers", + "label.website": "Website", + "label.website-id": "Website ID", + "label.websites": "Websites", + "label.window": "Window", + "label.yesterday": "Gisteren", + "message.active-users": "{x} actieve {x, plural, one {bezoeker} other {bezoekers}}", + "message.confirm-delete": "Weet je zeker dat je {target} wilt verwijderen?", + "message.confirm-leave": "Weet je zeker dat je {target} wilt verlaten?", + "message.confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", + "message.delete-website-warning": "Alle verwante gegezens zullen ook verwijderd worden.", + "message.error": "Er is iets misgegaan.", + "message.event-log": "{event} op {url}", + "message.go-to-settings": "Naar instellingen", + "message.incorrect-username-password": "Incorrecte gebruikersnaam/wachtwoord.", + "message.invalid-domain": "Ongeldig domein", + "message.min-password-length": "Minimale lengte van {n} tekens", + "message.new-version-available": "A new version of Umami {version} is available!", + "message.no-data-available": "Geen gegevens beschikbaar.", + "message.no-event-data": "No event data is available.", + "message.no-match-password": "Wachtwoorden komen niet overeen", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "Er zijn geen websites gekoppeld aan dit team.", + "message.no-teams": "Er zijn nog geen teams aangemaakt.", + "message.no-users": "Er zijn geen gebruikers.", + "message.no-websites-configured": "Je hebt geen websites ingesteld.", + "message.page-not-found": "Pagina niet gevonden.", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", + "message.reset-website-warning": "Alle bijhorende statistieken van deze website worden verwijderd, maar jouw volgcode blijft gelden.", + "message.saved": "Opslaan succesvol.", + "message.share-url": "Met deze URL kan {target} openbaar gedeeld worden.", + "message.team-already-member": "Je bent al lid van het team.", + "message.team-not-found": "Team niet gevonden.", + "message.team-websites-info": "Websites kunnen door iedereen in het team worden bekeken.", + "message.tracking-code": "Volgcode", + "message.user-deleted": "Gebruiker verwijderd.", + "message.visitor-log": "Bezoeker uit {country} met {browser} op een {os} {device}" +} diff --git a/lang/pl-PL.json b/src/lang/pl-PL.json similarity index 66% rename from lang/pl-PL.json rename to src/lang/pl-PL.json index 919fd9b3..eb940613 100644 --- a/lang/pl-PL.json +++ b/src/lang/pl-PL.json @@ -2,23 +2,34 @@ "label.access-code": "Kod dostępu", "label.actions": "Działania", "label.activity-log": "Dziennik aktywności", + "label.add": "Dodaj", + "label.add-description": "Dodaj opis", "label.add-website": "Dodaj witrynę", "label.admin": "Administrator", + "label.after": "Po", "label.all": "Wszystkie", "label.all-time": "Cały czas", "label.analytics": "Analityka", + "label.average": "Średnia", "label.average-visit-time": "Średni czas wizyty", "label.back": "Powrót", + "label.before": "Przed", "label.bounce-rate": "Współczynnik odrzuceń", + "label.breakdown": "Rozbicie", + "label.browser": "Browser", "label.browsers": "Przeglądarki", "label.cancel": "Anuluj", "label.change-password": "Zmień hasło", "label.cities": "Miasta", + "label.city": "City", "label.clear-all": "Wyczyść wszystko", "label.confirm": "Potwierdź", "label.confirm-password": "Potwierdź hasło", + "label.contains": "Zawiera", "label.continue": "Kontynuuj", "label.countries": "Kraje", + "label.country": "Country", + "label.create-report": "Stwórz raport", "label.create-team": "Utwórz zespół", "label.create-user": "Utwórz użytkownika", "label.created": "Utworzony", @@ -26,23 +37,43 @@ "label.custom-range": "Zakres niestandardowy", "label.dashboard": "Panel", "label.data": "Data", + "label.date": "Date", "label.date-range": "Zakres dat", + "label.day": "Day", "label.default-date-range": "Domyślny zakres dat", "label.delete": "Usuń", "label.delete-team": "Usuń zespół", "label.delete-user": "Usuń użytkownika", "label.delete-website": "Usuń witrynę", + "label.description": "Opis", "label.desktop": "Komputer", "label.details": "Szczegóły", + "label.device": "Device", "label.devices": "Urządzenia", "label.dismiss": "Odrzuć", + "label.does-not-contain": "Nie zawiera", "label.domain": "Domena", + "label.dropoff": "Dropoff", "label.edit": "Edytuj", "label.edit-dashboard": "Edytuj panel", "label.enable-share-url": "Włącz udostępnianie adresu URL", + "label.event": "Event", + "label.event-data": "Dane zdarzenia", "label.events": "Zdarzenia", + "label.false": "Fałsz", + "label.field": "Pole", + "label.fields": "Pola", "label.filter-combined": "Połączone", "label.filter-raw": "Surowe dane", + "label.filters": "Filtry", + "label.funnel": "Lejek", + "label.greater-than": "Większe niż", + "label.greater-than-equals": "Większe niż lub równe", + "label.insights": "Insights", + "label.is": "Równe", + "label.is-not": "Nie jest równe", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Dołącz", "label.join-team": "Dołącz do zespołu", "label.language": "Język", @@ -52,46 +83,64 @@ "label.last-hours": "Ostatnie {x} godzin", "label.leave": "Opuść", "label.leave-team": "Opuść zespół", + "label.less-than": "Mniejsze niż", + "label.less-than-equals": "Mniejsze niż lub równe", "label.login": "Zaloguj się", "label.logout": "Wyloguj", + "label.max": "Maks", "label.members": "Członkowie", + "label.min": "Min", "label.mobile": "Smartfon", "label.more": "Więcej", + "label.my-websites": "My websites", "label.name": "Nazwa", "label.new-password": "Nowe hasło", "label.none": "Brak", - "label.operating-systems": "System operacyjny", + "label.os": "OS", + "label.overview": "Przegląd", "label.owner": "Właściciel", + "label.page-of": "Page {current} of {total}", "label.page-views": "Wyświetlenia strony", + "label.pageTitle": "Page title", "label.pages": "Strony", "label.password": "Hasło", "label.powered-by": "Obsługiwane przez {name}", "label.profile": "Profil", "label.queries": "Zapytania", - "label.query-parameters": "Parametry query", + "label.query": "Zapytanie", + "label.query-parameters": "Parametry zapytania", "label.realtime": "Czas rzeczywisty", + "label.referrer": "Referrer", "label.referrers": "Źródła odsyłające", "label.refresh": "Odśwież", "label.regenerate": "Wygeneruj ponownie", + "label.region": "Region", "label.regions": "Regiony", "label.remove": "Usuń", + "label.reports": "Raporty", "label.required": "Wymagany", "label.reset": "Zresetuj", "label.reset-website": "Zresetuj statystyki", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Uruchom zapytanie", "label.save": "Zapisz", "label.screens": "Ekrany", + "label.select-date": "Wybierz datę", "label.select-website": "Wybierz witrynę", "label.sessions": "Sesje", "label.settings": "Ustawienia", "label.share-url": "Udostępnij adres URL", "label.single-day": "W tym dniu", + "label.sum": "Suma", "label.tablet": "Tablet", "label.team": "Zespół", "label.team-guest": "Gość zespołu", "label.team-id": "ID zespołu", "label.team-member": "Członek zespołu", + "label.team-name": "Team name", "label.team-owner": "Właściciel zespołu", + "label.team-websites": "Team websites", "label.teams": "Zespoły", "label.theme": "Motyw", "label.this-month": "W tym miesiącu", @@ -101,24 +150,37 @@ "label.title": "Tytuł", "label.today": "Dzisiaj", "label.toggle-charts": "Przełącz wykresy", + "label.total": "W sumie", + "label.total-records": "Suma rekordów", "label.tracking-code": "Kod śledzenia", + "label.true": "Prawda", + "label.type": "Typ", + "label.unique": "Unikalne", "label.unique-visitors": "Unikalni odwiedzający", "label.unknown": "Nieznany", + "label.untitled": "Bez tytułu", + "label.url": "Link", + "label.urls": "Linki", "label.user": "Użytkownik", "label.username": "Nazwa użytkownika", "label.users": "Użytkownicy", + "label.value": "Wartość", "label.view": "Zobacz", "label.view-details": "Pokaż szczegóły", + "label.view-only": "Tylko do odczytu", "label.views": "Wyświetlenia", "label.visitors": "Odwiedzający", + "label.website": "Witryna", "label.website-id": "ID witryny", "label.websites": "Witryny", + "label.window": "Okno", "label.yesterday": "Wczoraj", "message.active-users": "{x} aktualnie {x, plural, one {odwiedzający} other {odwiedzających}}", "message.confirm-delete": "Czy na pewno chcesz usunąć {target}?", "message.confirm-leave": "Czy na pewno chcesz opuścić {target}?", "message.confirm-reset": "Czy na pewno chcesz zresetować statystyki {target}?", - "message.delete-website": "Usuń witrynę", + "message.delete-account": "Aby usunąć to konto, wpisz {confirmation} w polu poniżej, aby potwierdzić.", + "message.delete-website": "Aby usunąć tę stronę, wpisz {confirmation} w polu poniżej, aby potwierdzić.", "message.delete-website-warning": "Wszystkie powiązane dane również zostaną usunięte.", "message.error": "Coś poszło nie tak.", "message.event-log": "{event} na {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nieprawidłowa nazwa użytkownika/hasło.", "message.invalid-domain": "Nieprawidłowa witryna", "message.min-password-length": "Minimalna długość {n} znaków", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Brak dostępnych danych.", + "message.no-event-data": "Brak dostępnych danych o zdarzeniach.", "message.no-match-password": "Hasła się nie zgadzają", + "message.no-results-found": "Nie znaleziono wyników.", + "message.no-team-websites": "Ten zespół nie ma żadnych witryn internetowych.", "message.no-teams": "Nie stworzyłeś żadnych zespołów.", "message.no-users": "Nie ma żadnych użytkowników.", + "message.no-websites-configured": "Nie masz skonfigurowanych żadnych witryn internetowych.", "message.page-not-found": "Strona nie znaleziona.", - "message.reset-website": "Zresetuj statystyki", + "message.reset-website": "Aby zresetować tę witrynę, wpisz {confirmation} w polu poniżej, aby potwierdzić.", "message.reset-website-warning": "Wszystkie statystyki tej witryny zostaną usunięte, ale kod śledzenia pozostanie nienaruszony.", "message.saved": "Zapisano pomyślnie.", "message.share-url": "To jest publicznie udostępniany adres URL dla {target}.", "message.team-already-member": "Jesteś już członkiem zespołu.", "message.team-not-found": "Nie znaleziono zespołu.", + "message.team-websites-info": "Strony internetowe mogą być przeglądane przez każdego członka zespołu.", "message.tracking-code": "Kod śledzenia", "message.user-deleted": "Użytkownik usunięty.", - "message.visitor-log": "Odwiedzający z {country} używa {browser} na {os} {device}", - "messages.no-team-websites": "Ten zespół nie ma żadnych witryn internetowych.", - "messages.no-websites-configured": "Nie masz skonfigurowanych żadnych witryn internetowych.", - "messages.team-websites-info": "Strony internetowe mogą być przeglądane przez każdego członka zespołu." + "message.visitor-log": "Odwiedzający z {country} używa {browser} na {os} {device}" } diff --git a/src/lang/pt-BR.json b/src/lang/pt-BR.json new file mode 100644 index 00000000..b68d9615 --- /dev/null +++ b/src/lang/pt-BR.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Código de acesso", + "label.actions": "Ações", + "label.activity-log": "Log de atividade", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "Adicionar site", + "label.admin": "Administrador", + "label.after": "Depois", + "label.all": "Todos", + "label.all-time": "Todo o período", + "label.analytics": "Estatísticas", + "label.average": "Average", + "label.average-visit-time": "Tempo médio da visita", + "label.back": "Voltar", + "label.before": "Antes", + "label.bounce-rate": "Taxa de rejeição", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Navegadores", + "label.cancel": "Cancelar", + "label.change-password": "Alterar a senha", + "label.cities": "Cidades", + "label.city": "City", + "label.clear-all": "Limpar tudo", + "label.confirm": "Confirmar", + "label.confirm-password": "Confirme a nova senha", + "label.contains": "Contains", + "label.continue": "Continuar", + "label.countries": "Países", + "label.country": "Country", + "label.create-report": "Criar relatório", + "label.create-team": "Criar time", + "label.create-user": "Criar usuário", + "label.created": "Criado", + "label.current-password": "Senha atual", + "label.custom-range": "Intervalo personalizado", + "label.dashboard": "Painel", + "label.data": "Data", + "label.date": "Date", + "label.date-range": "Intervalo de datas", + "label.day": "Day", + "label.default-date-range": "Intervalo de datas predefinido", + "label.delete": "Remover", + "label.delete-team": "Remover time", + "label.delete-user": "Remover usuário", + "label.delete-website": "Remover site", + "label.description": "Descrição", + "label.desktop": "Computador", + "label.details": "Detalhes", + "label.device": "Device", + "label.devices": "Dispositivos", + "label.dismiss": "Dispensar", + "label.does-not-contain": "Does not contain", + "label.domain": "Domínio", + "label.dropoff": "Dropoff", + "label.edit": "Editar", + "label.edit-dashboard": "Editar painel", + "label.enable-share-url": "Ativar link de compartilhamento", + "label.event": "Evento", + "label.event-data": "Event data", + "label.events": "Eventos", + "label.false": "False", + "label.field": "Campo", + "label.fields": "Campos", + "label.filter-combined": "Combinado", + "label.filter-raw": "Dados brutos", + "label.filters": "Filters", + "label.funnel": "Funil", + "label.greater-than": "Maior que", + "label.greater-than-equals": "Maior que ou igual", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Entrar", + "label.join-team": "Entrar no time", + "label.language": "Idioma", + "label.languages": "Idiomas", + "label.laptop": "Notebook", + "label.last-days": "Últimos {x} dias", + "label.last-hours": "Últimas {x} horas", + "label.leave": "Sair", + "label.leave-team": "Sair do time", + "label.less-than": "Menor que", + "label.less-than-equals": "Menor que ou igual", + "label.login": "Iniciar sessão", + "label.logout": "Sair", + "label.max": "Max", + "label.members": "Membros", + "label.min": "Min", + "label.mobile": "Celular", + "label.more": "Mais", + "label.my-websites": "My websites", + "label.name": "Nome", + "label.new-password": "Nova senha", + "label.none": "Nenhum", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "Proprietário", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Visualizações de página", + "label.pageTitle": "Page title", + "label.pages": "Páginas", + "label.password": "Senha", + "label.powered-by": "Distribuído por {name}", + "label.profile": "Perfil", + "label.queries": "Parâmetros", + "label.query": "Query", + "label.query-parameters": "Parâmetros de Consulta", + "label.realtime": "Tempo real", + "label.referrer": "Referrer", + "label.referrers": "Referências", + "label.refresh": "Atualizar", + "label.regenerate": "Regerar", + "label.region": "Region", + "label.regions": "Regiões", + "label.remove": "Remover", + "label.reports": "Reports", + "label.required": "Obrigatório", + "label.reset": "Redefinir", + "label.reset-website": "Redefinir estatísticas", + "label.retention": "Retention", + "label.role": "Papel", + "label.run-query": "Executar query", + "label.save": "Salvar", + "label.screens": "Telas", + "label.select-date": "Selecionar data", + "label.select-website": "Selecionar site", + "label.sessions": "Sessões", + "label.settings": "Configurações", + "label.share-url": "Link de compartilhamento", + "label.single-day": "Dia específico", + "label.sum": "Sum", + "label.tablet": "Tablet", + "label.team": "Time", + "label.team-guest": "Convidado", + "label.team-id": "ID do Time", + "label.team-member": "Membro", + "label.team-name": "Team name", + "label.team-owner": "Proprietário", + "label.team-websites": "Team websites", + "label.teams": "Times", + "label.theme": "Tema", + "label.this-month": "Este mês", + "label.this-week": "Esta semana", + "label.this-year": "Este ano", + "label.timezone": "Fuso horário", + "label.title": "Título", + "label.today": "Hoje", + "label.toggle-charts": "Mostrar/Esconder gráficos", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Código de rastreamento", + "label.true": "True", + "label.type": "Tipo", + "label.unique": "Único", + "label.unique-visitors": "Visitantes únicos", + "label.unknown": "Desconhecido", + "label.untitled": "Sem título", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "Usuário", + "label.username": "Nome de usuário", + "label.users": "Usuários", + "label.value": "Valor", + "label.view": "Ver", + "label.view-details": "Ver detalhes", + "label.view-only": "Somente visualização", + "label.views": "Visualizações", + "label.visitors": "Visitantes", + "label.website": "Website", + "label.website-id": "ID do Site", + "label.websites": "Sites", + "label.window": "Janela", + "label.yesterday": "Ontem", + "message.active-users": "{x} {x, plural, one {visitante} other {visitantes}} neste momento", + "message.confirm-delete": "Deseja realmente remover {target}?", + "message.confirm-leave": "Você tem certeza que deseja sair de {target}?", + "message.confirm-reset": "Você tem certeza que deseja redefinir as estatísticas de {target}?", + "message.delete-account": "Para excluir esta conta, digite {confirmation} na caixa abaixo para confirmar.", + "message.delete-website": "Para excluir este website, digite {confirmation} na caixa abaixo para confirmar.", + "message.delete-website-warning": "Todos os dados associados também serão eliminados.", + "message.error": "Ocorreu um erro.", + "message.event-log": "{event} em {url}", + "message.go-to-settings": "Ir para as configurações", + "message.incorrect-username-password": "O nome de usuário e/ou senha está incorreto.", + "message.invalid-domain": "Domínio inválido", + "message.min-password-length": "Quantidade mínima de {n} caracteres", + "message.new-version-available": "Uma nova versão do Umami {version} está disponível!", + "message.no-data-available": "Sem dados disponíveis.", + "message.no-event-data": "Nenhum dado de evento está disponível.", + "message.no-match-password": "As senhas não correspondem", + "message.no-results-found": "Nenhum resultado foi encontrado.", + "message.no-team-websites": "Este time não possui nenhum site.", + "message.no-teams": "Você não criou nenhum time.", + "message.no-users": "Não há nenhum usuário.", + "message.no-websites-configured": "Nenhum site foi configurado ainda.", + "message.page-not-found": "Página não encontrada.", + "message.reset-website": "Para redefinir este site, digite {confirmation} na caixa abaixo para confirmar.", + "message.reset-website-warning": "Todas as estatísticas deste site serão removidas, mas seu código de rastreamento permanecerá intacto.", + "message.saved": "Salvo com sucesso.", + "message.share-url": "Este é o link público de compartilhamento para {target}.", + "message.team-already-member": "Você já um membro do time.", + "message.team-not-found": "Time não encontrado.", + "message.team-websites-info": "Os sites podem ser visualizados por qualquer membro da equipe.", + "message.tracking-code": "Código de rastreamento", + "message.user-deleted": "Usuário removido.", + "message.visitor-log": "Visitante de {country} usando {browser} no {device} {os}" +} diff --git a/lang/pt-PT.json b/src/lang/pt-PT.json similarity index 67% rename from lang/pt-PT.json rename to src/lang/pt-PT.json index e67479e5..fcf7ff03 100644 --- a/lang/pt-PT.json +++ b/src/lang/pt-PT.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Ações", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Adicionar website", "label.admin": "Administrador", + "label.after": "After", "label.all": "Todos", "label.all-time": "Todo o tempo", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Tempo médio de visita", "label.back": "Voltar", + "label.before": "Before", "label.bounce-rate": "Taxa de rejeição", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Navegadores", "label.cancel": "Cancelar", "label.change-password": "Alterar senha", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Confirmar senha", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Países", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Intervalo personalizado", "label.dashboard": "Painel", "label.data": "Data", + "label.date": "Date", "label.date-range": "Intervalo de datas", + "label.day": "Day", "label.default-date-range": "Intervalo de datas predefinido", "label.delete": "Eliminar", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Eliminar website", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Dispositivos", "label.dismiss": "Ignorar", + "label.does-not-contain": "Does not contain", "label.domain": "Domínio", + "label.dropoff": "Dropoff", "label.edit": "Editar", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Ativar link de partilha", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Eventos", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Combinado", "label.filter-raw": "Dados brutos", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Língua", @@ -52,46 +83,64 @@ "label.last-hours": "Últimas {x} horas", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Iniciar sessão", "label.logout": "Sair", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Telemóvel", "label.more": "Mais", + "label.my-websites": "My websites", "label.name": "Nome", "label.new-password": "Nova senha", "label.none": "None", - "label.operating-systems": "Sistemas operativos", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Proprietário", + "label.page-of": "Page {current} of {total}", "label.page-views": "Visualizações da página", + "label.pageTitle": "Page title", "label.pages": "Páginas", "label.password": "Senha", "label.powered-by": "Distribuído por {name}", "label.profile": "Perfil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Tempo real", + "label.referrer": "Referrer", "label.referrers": "Referenciadores", "label.refresh": "Atualizar", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Obrigatório", "label.reset": "Repor", "label.reset-website": "Repor estatísticas", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Guardar", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Definições", "label.share-url": "Partilhar link", "label.single-day": "Dia único", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Tema", "label.this-month": "Este mês", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Hoje", "label.toggle-charts": "Alternar gráficos", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Código de rastreamento", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Visitantes únicos", "label.unknown": "Desconhecido", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Nome de utilizador", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Ver detalhes", + "label.view-only": "View only", "label.views": "Visualizações", "label.visitors": "Visitantes", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Websites", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} {x, plural, one {visitante} other {visitantes}} neste momento", "message.confirm-delete": "Tem a certeza que pretende eliminar {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Tem a certeza que pretende restaurar as estatísticas de {target}?", - "message.delete-website": "Eliminar website", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Todos os dados associados também serão eliminados.", "message.error": "Ocorreu um erro.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nome de utilizador/senha incorretos.", "message.invalid-domain": "Domínio inválido", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Sem dados disponíveis.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "As senhas não coincidem", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Não tens nenhum website configurado.", "message.page-not-found": "Página não encontrada.", - "message.reset-website": "Repor estatísticas", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Todas as estatísticas deste site serão eliminadas, mas o seu código de rastreamento permanecerá intacto.", "message.saved": "Guardado com sucesso.", "message.share-url": "Este é o link de partilha público para {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Código de rastreamento", "message.user-deleted": "User deleted.", - "message.visitor-log": "Visitante de {country} a usar {browser} no {device} {os}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Não tens nenhum website configurado.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Visitante de {country} a usar {browser} no {device} {os}" } diff --git a/lang/ro-RO.json b/src/lang/ro-RO.json similarity index 67% rename from lang/ro-RO.json rename to src/lang/ro-RO.json index deefd899..43a78ecd 100644 --- a/lang/ro-RO.json +++ b/src/lang/ro-RO.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Acțiuni", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Adăugare site web", "label.admin": "Administrator", + "label.after": "After", "label.all": "Toate", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Timp mediu de vizitare", "label.back": "Înapoi", + "label.before": "Before", "label.bounce-rate": "Rata de respingere", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Browsere", "label.cancel": "Anulează", "label.change-password": "Schimbare parolă", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Confirmare parolă", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Țări", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Interval personalizat", "label.dashboard": "Tablou de bord", "label.data": "Data", + "label.date": "Date", "label.date-range": "Interval de date", + "label.day": "Day", "label.default-date-range": "Interval de date implicit", "label.delete": "Șterge", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Ștergere site web", + "label.description": "Description", "label.desktop": "Desktop", "label.details": "Details", + "label.device": "Device", "label.devices": "Dispozitive", "label.dismiss": "Renunță", + "label.does-not-contain": "Does not contain", "label.domain": "Domeniu", + "label.dropoff": "Dropoff", "label.edit": "Editare", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Activare adresă URL de distribuire", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Evenimente", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Combinat", "label.filter-raw": "Brut", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Ultimele {x} ore", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Autentificare", "label.logout": "Iesire din cont", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobil", "label.more": "Mai mult", + "label.my-websites": "My websites", "label.name": "Nume", "label.new-password": "Parola nouă", "label.none": "None", - "label.operating-systems": "Sisteme de operare", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Vizualizări de pagină", + "label.pageTitle": "Page title", "label.pages": "Pagini", "label.password": "Parolă", "label.powered-by": "Cu sprijinul {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Realtime", + "label.referrer": "Referrer", "label.referrers": "Site-uri de proveniență", "label.refresh": "Reîmprospătare", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Obligatoriu", "label.reset": "Resetează", "label.reset-website": "Resetează statisticile pentru site", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Salvează", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Setări", "label.share-url": "Partajare URL", "label.single-day": "O singură zi", + "label.sum": "Sum", "label.tablet": "Tabletă", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Această lună", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Astăzi", "label.toggle-charts": "Schimbă graficele", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Cod de urmărire", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Vizitatori unici", "label.unknown": "Necunoscut", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Nume utilizator", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Vizualizare detalii", + "label.view-only": "View only", "label.views": "Vizualizări", "label.visitors": "Vizitatori", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Site-uri web", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} {x, plural, one {vizitator activ} other {vizitatori activi}}", "message.confirm-delete": "Sunteți sigur că doriți să ștergeți {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Sunteți sigur că doriți să resetați statisticile pentru {target}?", - "message.delete-website": "Ștergere site web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Toate datele asociate vor fi șterse, de asemenea.", "message.error": "Ceva n-a mers bine.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nume utilizator / parolă incorecte.", "message.invalid-domain": "Domeniu nu este valid", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Nici o informație disponibilă.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Parolele nu se potrivesc", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Nu aveți niciun site web configurat.", "message.page-not-found": "Pagina nu a fost găsită.", - "message.reset-website": "Resetează statisticile pentru site", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Toate statisticile pentru acest site web vor fi șterse, dar codul de urmărire va rămâne intact.", "message.saved": "Salvat cu succes.", "message.share-url": "Aceasta este adresa URL de partajare pentru {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Cod de urmărire", "message.user-deleted": "User deleted.", - "message.visitor-log": "Vizitator din {country} folosind {browser} pe {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Nu aveți niciun site web configurat.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Vizitator din {country} folosind {browser} pe {os} {device}" } diff --git a/lang/ru-RU.json b/src/lang/ru-RU.json similarity index 72% rename from lang/ru-RU.json rename to src/lang/ru-RU.json index c5093c8c..b9129beb 100644 --- a/lang/ru-RU.json +++ b/src/lang/ru-RU.json @@ -2,23 +2,34 @@ "label.access-code": "Код доступа", "label.actions": "Действия", "label.activity-log": "Журнал активности", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Добавить сайт", "label.admin": "Администратор", + "label.after": "After", "label.all": "Все", "label.all-time": "Все время", "label.analytics": "Аналитика", + "label.average": "Average", "label.average-visit-time": "Среднее время посещения", "label.back": "Назад", + "label.before": "Before", "label.bounce-rate": "Отказы", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Браузеры", "label.cancel": "Отменить", "label.change-password": "Изменить пароль", "label.cities": "Города", + "label.city": "City", "label.clear-all": "Очистить все", "label.confirm": "Подтвердить", "label.confirm-password": "Подтвердить пароль", + "label.contains": "Contains", "label.continue": "Продолжить", "label.countries": "Страны", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Создать команду", "label.create-user": "Создать пользователя", "label.created": "Создано", @@ -26,23 +37,43 @@ "label.custom-range": "Другой период", "label.dashboard": "Информационная панель", "label.data": "Данные", + "label.date": "Date", "label.date-range": "Диапазон дат", + "label.day": "Day", "label.default-date-range": "Диапазон дат по-умолчанию", "label.delete": "Удалить", "label.delete-team": "Удалить команду", "label.delete-user": "Удалить пользователя", "label.delete-website": "Удалить сайт", + "label.description": "Description", "label.desktop": "Настольный компьютер", "label.details": "Подробности", + "label.device": "Device", "label.devices": "Устройства", "label.dismiss": "Отклонить", + "label.does-not-contain": "Does not contain", "label.domain": "Домен", - "label.edit": "Редактировать", + "label.dropoff": "Dropoff", + "label.edit": "Изменить", "label.edit-dashboard": "Редактировать дашборд", "label.enable-share-url": "Разрешить делиться ссылкой", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "События", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Объединенные", "label.filter-raw": "Сырые данные", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Присоединиться", "label.join-team": "Присоединиться к команде", "label.language": "Язык", @@ -52,46 +83,64 @@ "label.last-hours": "Последние {x} часа", "label.leave": "Уйти", "label.leave-team": "Покинуть команду", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Войти", "label.logout": "Выйти", + "label.max": "Max", "label.members": "Участники", + "label.min": "Min", "label.mobile": "Смартфон", "label.more": "Больше", + "label.my-websites": "My websites", "label.name": "Имя", "label.new-password": "Новый пароль", "label.none": "Не указано", - "label.operating-systems": "Операционные системы", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Владелец", + "label.page-of": "Page {current} of {total}", "label.page-views": "Просмотры страниц", + "label.pageTitle": "Page title", "label.pages": "Страницы", "label.password": "Пароль", "label.powered-by": "На движке {name}", "label.profile": "Профиль", "label.queries": "Запросы", + "label.query": "Query", "label.query-parameters": "Параметры запроса", "label.realtime": "Реальное время", + "label.referrer": "Referrer", "label.referrers": "Источники", "label.refresh": "Обновить", "label.regenerate": "Обновить", + "label.region": "Region", "label.regions": "Регионы", "label.remove": "Удалить", + "label.reports": "Reports", "label.required": "Обязательное", "label.reset": "Сбросить", "label.reset-website": "Сбросить статистику", + "label.retention": "Retention", "label.role": "Роль", + "label.run-query": "Run query", "label.save": "Сохранить", "label.screens": "Экраны", + "label.select-date": "Select date", "label.select-website": "Выбрать сайт", "label.sessions": "Сессии", "label.settings": "Настройки", "label.share-url": "Поделиться ссылкой", "label.single-day": "Один день", + "label.sum": "Sum", "label.tablet": "Планшет", "label.team": "Команда", "label.team-guest": "Гость команды", "label.team-id": "ID команды", "label.team-member": "Член команды", + "label.team-name": "Team name", "label.team-owner": "Владелец команды", + "label.team-websites": "Team websites", "label.teams": "Команды", "label.theme": "Тема", "label.this-month": "Этот месяц", @@ -101,24 +150,37 @@ "label.title": "Заголовок", "label.today": "Сегодня", "label.toggle-charts": "Показать/скрыть графики", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Код отслеживания", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Уникальные посетители", "label.unknown": "Неизвестно", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "Пользователь", "label.username": "Имя пользователя", "label.users": "Пользователи", + "label.value": "Value", "label.view": "Просмотреть", "label.view-details": "Посмотреть детали", + "label.view-only": "View only", "label.views": "Просмотры", "label.visitors": "Посетители", + "label.website": "Website", "label.website-id": "ID сайта", "label.websites": "Сайты", + "label.window": "Window", "label.yesterday": "Вчера", "message.active-users": "{x} текущих посетителей", "message.confirm-delete": "Вы уверены, что хотите удалить {target}?", "message.confirm-leave": "Вы уверены, что хотите уйти {target}?", "message.confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?", - "message.delete-website": "Удалить сайт", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "Для удаления введите DELETE", "message.delete-website-warning": "Все связанные данные будут также удалены.", "message.error": "Что-то пошло не так.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "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.no-data-available": "Нет данных.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Пароли не совпадают", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "У этой команды нет ни одного сайта.", "message.no-teams": "Вы не создали ни одной команды.", "message.no-users": "Нет пользователей.", + "message.no-websites-configured": "У вас нет настроенных сайтов.", "message.page-not-found": "Страница не найдена.", - "message.reset-website": "Сбросить статистику", + "message.reset-website": "Для сброса введите RESET", "message.reset-website-warning": "Вся статистика для этого сайта будет удалена, но ваш код отслеживания останется нетронутым.", "message.saved": "Успешно сохранено.", "message.share-url": "Это публичная ссылка для {target}.", "message.team-already-member": "Вы уже состоите в команде.", "message.team-not-found": "Команда не найдена.", + "message.team-websites-info": "Сайты могут просматривать все члены команды.", "message.tracking-code": "Код отслеживания", "message.user-deleted": "Пользователь удален.", - "message.visitor-log": "Посетитель из {country} используя {browser} на {os} {device}", - "messages.no-team-websites": "У этой команды нет ни одного сайта.", - "messages.no-websites-configured": "У вас нет настроенных сайтов.", - "messages.team-websites-info": "Сайты могут просматривать все члены команды." + "message.visitor-log": "Посетитель из {country} используя {browser} на {os} {device}" } diff --git a/src/lang/si-LK.json b/src/lang/si-LK.json new file mode 100644 index 00000000..6f6dda6d --- /dev/null +++ b/src/lang/si-LK.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Access code", + "label.actions": "Actions", + "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "වෙබ් අඩවිය එක් කරන්න", + "label.admin": "Administrator", + "label.after": "After", + "label.all": "සියල්ල", + "label.all-time": "හැම වෙලාවෙම", + "label.analytics": "Analytics", + "label.average": "Average", + "label.average-visit-time": "Average visit time", + "label.back": "ආපසු", + "label.before": "Before", + "label.bounce-rate": "Bounce rate", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Browsers", + "label.cancel": "අවලංගු කරන්න", + "label.change-password": "මුරපදය වෙනස් කරන්න", + "label.cities": "Cities", + "label.city": "City", + "label.clear-all": "Clear all", + "label.confirm": "Confirm", + "label.confirm-password": "මුරපදය සත්‍යාපනය කරන්න", + "label.contains": "Contains", + "label.continue": "Continue", + "label.countries": "Countries", + "label.country": "Country", + "label.create-report": "Create report", + "label.create-team": "Create team", + "label.create-user": "Create user", + "label.created": "Created", + "label.current-password": "වත්මන් මුරපදය", + "label.custom-range": "අභිරුචි පරාසය", + "label.dashboard": "උපකරණ පුවරුව", + "label.data": "Data", + "label.date": "Date", + "label.date-range": "දින පරාසය", + "label.day": "Day", + "label.default-date-range": "පෙරනිමි දින පරාසය", + "label.delete": "මකන්න", + "label.delete-team": "Delete team", + "label.delete-user": "Delete user", + "label.delete-website": "වෙබ් අඩවිය මකන්න", + "label.description": "Description", + "label.desktop": "Desktop", + "label.details": "Details", + "label.device": "Device", + "label.devices": "Devices", + "label.dismiss": "මගහරින්න", + "label.does-not-contain": "Does not contain", + "label.domain": "වසම", + "label.dropoff": "Dropoff", + "label.edit": "සංස්කරණය කරන්න", + "label.edit-dashboard": "Edit dashboard", + "label.enable-share-url": "බෙදාගැනීමේ URL සබල කරන්න", + "label.event": "Event", + "label.event-data": "සිදුවීම් දත්ත", + "label.events": "Events", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", + "label.filter-combined": "Combined", + "label.filter-raw": "Raw", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Join", + "label.join-team": "Join team", + "label.language": "භාෂාව", + "label.languages": "Languages", + "label.laptop": "Laptop", + "label.last-days": "අන්තිම {x} දින", + "label.last-hours": "අන්තිම {x} පැය", + "label.leave": "Leave", + "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", + "label.login": "ලොග් වෙන්න", + "label.logout": "පිටවීම", + "label.max": "Max", + "label.members": "Members", + "label.min": "Min", + "label.mobile": "Mobile", + "label.more": "තවත්", + "label.my-websites": "My websites", + "label.name": "නම", + "label.new-password": "අලුත් මුරපදය", + "label.none": "කිසිවක් නැත", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "හිමිකරු", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Page views", + "label.pageTitle": "Page title", + "label.pages": "Pages", + "label.password": "මුරපදය", + "label.powered-by": "Powered by {name}", + "label.profile": "පැතිකඩ", + "label.queries": "Queries", + "label.query": "Query", + "label.query-parameters": "Query parameters", + "label.realtime": "තත්ය කාල", + "label.referrer": "Referrer", + "label.referrers": "Referrers", + "label.refresh": "නැවුම් කරන්න", + "label.regenerate": "Regenerate", + "label.region": "Region", + "label.regions": "Regions", + "label.remove": "Remove", + "label.reports": "Reports", + "label.required": "අවශ්‍යයි", + "label.reset": "යළි පිහිටුවන්න", + "label.reset-website": "සංඛ්යා ලේඛන නැවත සකසන්න", + "label.retention": "Retention", + "label.role": "Role", + "label.run-query": "Run query", + "label.save": "සුරකින්න", + "label.screens": "Screens", + "label.select-date": "Select date", + "label.select-website": "Select website", + "label.sessions": "Sessions", + "label.settings": "සැකසුම්", + "label.share-url": "බෙදාගැනීමේ URL", + "label.single-day": "තනි දවස", + "label.sum": "Sum", + "label.tablet": "Tablet", + "label.team": "Team", + "label.team-guest": "Team guest", + "label.team-id": "Team ID", + "label.team-member": "Team member", + "label.team-name": "Team name", + "label.team-owner": "Team owner", + "label.team-websites": "Team websites", + "label.teams": "Teams", + "label.theme": "තේමාව", + "label.this-month": "මෙ මාසය", + "label.this-week": "මේ සතිය", + "label.this-year": "මේ අවුරුද්ද", + "label.timezone": "වේලා කලාපය", + "label.title": "Title", + "label.today": "අද", + "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "ලුහුබැඳීමේ කේතය", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", + "label.unique-visitors": "Unique visitors", + "label.unknown": "නොදනී", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "User", + "label.username": "පරිශීලක නාමය", + "label.users": "Users", + "label.value": "Value", + "label.view": "View", + "label.view-details": "තොරතුරු පෙන්වන්න", + "label.view-only": "View only", + "label.views": "Views", + "label.visitors": "Visitors", + "label.website": "Website", + "label.website-id": "Website ID", + "label.websites": "වෙබ් අඩවි", + "label.window": "Window", + "label.yesterday": "ඊයේ", + "message.active-users": "{x} දැන් {x, plural, one {අමුත්තා} other {අමුත්තන්}}", + "message.confirm-delete": "{target} මකා දැමීම ගැන විශ්වාසද?", + "message.confirm-leave": "Are you sure you want to leave {target}?", + "message.confirm-reset": "{target} ට අදාල සංඛ්‍යාලේඛන නැවත පිහිටුවීමට අවශ්‍යද?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", + "message.delete-website-warning": "All website data will be deleted.", + "message.error": "Something went wrong.", + "message.event-log": "{event} on {url}", + "message.go-to-settings": "සැකසීම් වෙත යන්න", + "message.incorrect-username-password": "වැරදි පරිශීලක නාමය/මුරපදය.", + "message.invalid-domain": "Invalid domain. Do not include http/https.", + "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", + "message.no-data-available": "පෙන්වීමට දත්ත නොමැත.", + "message.no-event-data": "No event data is available.", + "message.no-match-password": "Passwords do not match.", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", + "message.no-teams": "You have not created any teams.", + "message.no-users": "There are no users.", + "message.no-websites-configured": "You do not have any websites configured.", + "message.page-not-found": "පිටුව හමු නොවීය.", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", + "message.reset-website-warning": "All statistics for this website will be deleted, but your settings will remain intact.", + "message.saved": "Saved.", + "message.share-url": "මේ {target} සඳහා ප්‍රසිද්ධියේ බෙදාගත් URL එකයි.", + "message.team-already-member": "You are already a member of the team.", + "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", + "message.tracking-code": "To track stats for this website, place the following code in the ... section of your HTML.", + "message.user-deleted": "User deleted.", + "message.visitor-log": "Visitor from {country} using {browser} on {os} {device}" +} diff --git a/lang/sk-SK.json b/src/lang/sk-SK.json similarity index 66% rename from lang/sk-SK.json rename to src/lang/sk-SK.json index 2d05cd2e..3f033923 100644 --- a/lang/sk-SK.json +++ b/src/lang/sk-SK.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Akcie", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Pridať web", "label.admin": "Administrátor", + "label.after": "After", "label.all": "Všetko", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Priemerný čas návštevy", "label.back": "Späť", + "label.before": "Before", "label.bounce-rate": "Okamžité opustenie", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Prehliadač", "label.cancel": "Zrušiť", "label.change-password": "Zmeniť heslo", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Potvrdiť heslo", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Zem", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Vlastný rozsah", "label.dashboard": "Prehlad", "label.data": "Data", + "label.date": "Date", "label.date-range": "Obdobie", + "label.day": "Day", "label.default-date-range": "Predvolené obdobie", "label.delete": "Zmazať", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Zmazať web", + "label.description": "Description", "label.desktop": "Stolný počítač", "label.details": "Details", + "label.device": "Device", "label.devices": "Zariadenie", "label.dismiss": "Odísť", + "label.does-not-contain": "Does not contain", "label.domain": "Doména", + "label.dropoff": "Dropoff", "label.edit": "Upraviť", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Povoliť zdielanie URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Udalosti", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Kombinácie", "label.filter-raw": "Nezpracované", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Posledných {x} hodín", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Prihlásiť", "label.logout": "Odhlásiť", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobilný telefon", "label.more": "Viac", + "label.my-websites": "My websites", "label.name": "Meno", "label.new-password": "Nové heslo", "label.none": "None", - "label.operating-systems": "Operačný systém", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Zobrazenie stánok", + "label.pageTitle": "Page title", "label.pages": "Stránky", "label.password": "Heslo", "label.powered-by": "Powered by {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Aktuálne", + "label.referrer": "Referrer", "label.referrers": "Odkazy", "label.refresh": "Obnoviť", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Povinné", "label.reset": "Reset", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Uložiť", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Nastavenia", "label.share-url": "Zdielanie URL", "label.single-day": "Jeden deň", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Tento mesiac", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Dnes", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Sledovací kód", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Jedinečné návštevy", "label.unknown": "Neznámý", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Užívateľské meno", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Zobraziť detaily", + "label.view-only": "View only", "label.views": "Zobrazení", "label.visitors": "Návštevy", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Weby", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} aktuálne {x, plural, one {návštevník} other {návštěvníci}}", "message.confirm-delete": "Naozaj zmazať {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Zmazať web", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Všetky príbuzné data budu tiež zmazané.", "message.error": "Niečo sa pokazilo.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nesprávné meno/heslo.", "message.invalid-domain": "Neplatná doména", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Žiadne data.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Hesla se nezhodujú", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Nemáte nastavený žiadny web.", "message.page-not-found": "Stránka sa nenašla.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Úspešne uložené.", "message.share-url": "Toto je zdielané URL pre {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Sledovací kód", "message.user-deleted": "User deleted.", - "message.visitor-log": "Návštevník z {country} s prehliadačom {browser} na {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Nemáte nastavený žiadny web.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Návštevník z {country} s prehliadačom {browser} na {os} {device}" } diff --git a/lang/sl-SI.json b/src/lang/sl-SI.json similarity index 67% rename from lang/sl-SI.json rename to src/lang/sl-SI.json index 459e5e7f..aae7888d 100644 --- a/lang/sl-SI.json +++ b/src/lang/sl-SI.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Dejanja", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Dodaj spletno mesto", "label.admin": "Administrator", + "label.after": "After", "label.all": "Vse", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Povprečni čas obiska", "label.back": "Nazaj", + "label.before": "Before", "label.bounce-rate": "Zapustna stopnja", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Brskalniki", "label.cancel": "Prekliči", "label.change-password": "Zamenjaj geslo", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Potrditev gesla", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Države", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Razpon po meri", "label.dashboard": "Nadzorna plošča", "label.data": "Data", + "label.date": "Date", "label.date-range": "Časovni razpon", + "label.day": "Day", "label.default-date-range": "Privzeti časovni razpon", "label.delete": "Izbriši", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Izbriši spletno mesto", + "label.description": "Description", "label.desktop": "Namizni računalnik", "label.details": "Details", + "label.device": "Device", "label.devices": "Naprave", "label.dismiss": "Opusti", + "label.does-not-contain": "Does not contain", "label.domain": "Domena", + "label.dropoff": "Dropoff", "label.edit": "Uredi", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Omogoči URL za skupno rabo", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Dogodki", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Skupno", "label.filter-raw": "Neobdelane meritve", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Zadnjih {x} ur", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Prijava", "label.logout": "Odjava", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobilni telefon", "label.more": "Več", + "label.my-websites": "My websites", "label.name": "Ime", "label.new-password": "Novo geslo", "label.none": "None", - "label.operating-systems": "Operacijski sistemi", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Ogledi strani", + "label.pageTitle": "Page title", "label.pages": "Strani", "label.password": "Geslo", "label.powered-by": "Zagotavlja {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "V realnem času", + "label.referrer": "Referrer", "label.referrers": "Viri", "label.refresh": "Osveži", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Zahtevano", "label.reset": "Ponastavi", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Shrani", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Nastavitve", "label.share-url": "Deli URL", "label.single-day": "En dan", + "label.sum": "Sum", "label.tablet": "Tablični računalnik", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Ta mesec", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Danes", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Koda za sledenje", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Unikatni obiskovalci", "label.unknown": "Neznano", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Uporabniško ime", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Prikaži podrobnosti", + "label.view-only": "View only", "label.views": "Ogledi", "label.visitors": "Obiskovalci", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Spletna mesta", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} trenutni {x, plural, one {obiskovalec} other {obiskovalcev}}", "message.confirm-delete": "Ste prepričani, da želite izbrisati {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Izbriši spletno mesto", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Izbrisani bodo tudi vsi povezani podatki.", "message.error": "Prišlo je do napake.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Nepravilno uporabniško ime/geslo", "message.invalid-domain": "Neveljavna domena", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Podatki niso na voljo.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Gesli se ne ujemata", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Ni nastavljenih spletnih mest.", "message.page-not-found": "Stran ni bila najdena.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Uspešno shranjeno.", "message.share-url": "To je javno dostopen naslov URL za {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Koda za sledenje", "message.user-deleted": "User deleted.", - "message.visitor-log": "Obiskovalec iz {country} uporablja {browser} na {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Ni nastavljenih spletnih mest.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Obiskovalec iz {country} uporablja {browser} na {os} {device}" } diff --git a/src/lang/sv-SE.json b/src/lang/sv-SE.json new file mode 100644 index 00000000..e6abb5bf --- /dev/null +++ b/src/lang/sv-SE.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "Access code", + "label.actions": "Händelser", + "label.activity-log": "Aktivitetslogg", + "label.add": "Add", + "label.add-description": "Add description", + "label.add-website": "Lägg till webbsajt", + "label.admin": "Administratör", + "label.after": "After", + "label.all": "Alla", + "label.all-time": "Sedan början", + "label.analytics": "Analys", + "label.average": "Average", + "label.average-visit-time": "Medelbesökstid", + "label.back": "Tillbaka", + "label.before": "Before", + "label.bounce-rate": "Avvisningfrekvens", + "label.breakdown": "Breakdown", + "label.browser": "Browser", + "label.browsers": "Webbläsare", + "label.cancel": "Avbryt", + "label.change-password": "Byt lösenord", + "label.cities": "Städer", + "label.city": "City", + "label.clear-all": "Rensa alla", + "label.confirm": "Bekräfta", + "label.confirm-password": "Bekräfta lösenord", + "label.contains": "Contains", + "label.continue": "Fortsätt", + "label.countries": "Länder", + "label.country": "Country", + "label.create-report": "Create report", + "label.create-team": "Skapa team", + "label.create-user": "Skapa användare", + "label.created": "Skapad", + "label.current-password": "Nuvarande lösenord", + "label.custom-range": "Anpassat urval", + "label.dashboard": "Översikt", + "label.data": "Data", + "label.date": "Date", + "label.date-range": "Datumomfång", + "label.day": "Day", + "label.default-date-range": "Standard datum-urval", + "label.delete": "Radera", + "label.delete-team": "Radera team", + "label.delete-user": "Radera användare", + "label.delete-website": "Radera webbsajt", + "label.description": "Description", + "label.desktop": "Stationär", + "label.details": "Detailjer", + "label.device": "Device", + "label.devices": "Enheter", + "label.dismiss": "Avbryt", + "label.does-not-contain": "Does not contain", + "label.domain": "Domän", + "label.dropoff": "Dropoff", + "label.edit": "Redigera", + "label.edit-dashboard": "Redigera översikt", + "label.enable-share-url": "Aktivera delnings-URL", + "label.event": "Event", + "label.event-data": "Event data", + "label.events": "Händelser", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", + "label.filter-combined": "Kombinerade", + "label.filter-raw": "Rådata", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", + "label.join": "Gå med", + "label.join-team": "gå med i team", + "label.language": "Språk", + "label.languages": "Språk", + "label.laptop": "Bärbar", + "label.last-days": "Senaste {x} dagarna", + "label.last-hours": "Senaste {x} timmarna", + "label.leave": "Lämna", + "label.leave-team": "Lämna team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", + "label.login": "Logga in", + "label.logout": "Logga ut", + "label.max": "Max", + "label.members": "Medlemmar", + "label.min": "Min", + "label.mobile": "Mobil", + "label.more": "Mer", + "label.my-websites": "My websites", + "label.name": "Namn", + "label.new-password": "Nytt lösenord", + "label.none": "Inga", + "label.os": "OS", + "label.overview": "Overview", + "label.owner": "Ägare", + "label.page-of": "Page {current} of {total}", + "label.page-views": "Sidvisningar", + "label.pageTitle": "Page title", + "label.pages": "Sidor", + "label.password": "Lösenord", + "label.powered-by": "Drivs av {name}", + "label.profile": "Profil", + "label.queries": "Frågor", + "label.query": "Frågor", + "label.query-parameters": "Fråge-parametrar", + "label.realtime": "Realtid", + "label.referrer": "Referrer", + "label.referrers": "Hänvisare", + "label.refresh": "Uppdatera", + "label.regenerate": "Regenerera", + "label.region": "Region", + "label.regions": "Regioner", + "label.remove": "Ta bort", + "label.reports": "Reports", + "label.required": "Krävs", + "label.reset": "Återställ", + "label.reset-website": "Återställ statistik", + "label.retention": "Retention", + "label.role": "Roll", + "label.run-query": "Run query", + "label.save": "Spara", + "label.screens": "Upplösning", + "label.select-date": "Select date", + "label.select-website": "Välj webbsajt", + "label.sessions": "Sessions", + "label.settings": "Inställningar", + "label.share-url": "Delnings-URL", + "label.single-day": "En dag", + "label.sum": "Sum", + "label.tablet": "Platta", + "label.team": "Team", + "label.team-guest": "Team-gäst", + "label.team-id": "Team ID", + "label.team-member": "Team-medlem", + "label.team-name": "Team name", + "label.team-owner": "Team-ägare", + "label.team-websites": "Team websites", + "label.teams": "Team", + "label.theme": "Tema", + "label.this-month": "Denna månad", + "label.this-week": "Denna vecka", + "label.this-year": "Detta år", + "label.timezone": "Tidszon", + "label.title": "Titel", + "label.today": "Idag", + "label.toggle-charts": "Visa/göm grafer", + "label.total": "Total", + "label.total-records": "Total records", + "label.tracking-code": "Spårningskod", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", + "label.unique-visitors": "Unika besökare", + "label.unknown": "Okänd", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", + "label.user": "Användare", + "label.username": "Användarnamn", + "label.users": "Users", + "label.value": "Value", + "label.view": "Visa", + "label.view-details": "Visa detaljer", + "label.view-only": "View only", + "label.views": "Visningar", + "label.visitors": "Besökare", + "label.website": "Website", + "label.website-id": "Webbsajt-ID", + "label.websites": "Webbsajt", + "label.window": "Window", + "label.yesterday": "Igår", + "message.active-users": "{x} {x, plural, one {besökare} other {besökare}} just nu", + "message.confirm-delete": "Är du säker på att du vill radera {target}?", + "message.confirm-leave": "Är du säker på att du vill lämna {target}?", + "message.confirm-reset": "Är du säker på att du vill återställa statistiken för {target}?", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", + "message.delete-website-warning": "All tillhörande data kommer också raderas.", + "message.error": "Något gick fel.", + "message.event-log": "{event} på {url}", + "message.go-to-settings": "Gå till inställningar", + "message.incorrect-username-password": "Felaktigt användarnamn/lösenord.", + "message.invalid-domain": "Ogiltig domän", + "message.min-password-length": "Minst {n} tecken", + "message.new-version-available": "A new version of Umami {version} is available!", + "message.no-data-available": "Ingen data tillgänglig.", + "message.no-event-data": "No event data is available.", + "message.no-match-password": "Lösenorden är inte samma", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "Det här teamet har inga webbsajter.", + "message.no-teams": "Du har inte skapat några team.", + "message.no-users": "Det finns inga användare.", + "message.no-websites-configured": "Du har inga webbsajter.", + "message.page-not-found": "Sidan kan inte hittas.", + "message.reset-website": "För att återställa statistiken skriv {confirmation} i rutan nedan.", + "message.reset-website-warning": "All statistik för webbsajten tas bort men spårningskoden förblir oförändrad.", + "message.saved": "Sparades!", + "message.share-url": "Det här är den offentliga delnings-URL:en för {target}.", + "message.team-already-member": "Du är redan medlem i teamet.", + "message.team-not-found": "Team kan inte hittas.", + "message.team-websites-info": "Websajter kan ses av alla i teamet.", + "message.tracking-code": "Spårningskod", + "message.user-deleted": "Användare raderad.", + "message.visitor-log": "Besökare från {country} med {browser} på {os} {device}" +} diff --git a/lang/ta-IN.json b/src/lang/ta-IN.json similarity index 73% rename from lang/ta-IN.json rename to src/lang/ta-IN.json index e4fc9f7e..be3d5e81 100644 --- a/lang/ta-IN.json +++ b/src/lang/ta-IN.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "செயல்கள்", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "வலைத்தளத்தைச் சேர்க்க", "label.admin": "நிர்வாகியைச் சேர்க்க", + "label.after": "After", "label.all": "எல்லாம்", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "சராசரி வருகை நேரம்", "label.back": "பின்னால்", + "label.before": "Before", "label.bounce-rate": "துள்ளல் விகிதம்", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "உலாவிகள்", "label.cancel": "ரத்துசெய்", "label.change-password": "கடவுச்சொல்லை மாற்று", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "கடவுச்சொல்லை உறுதிப்படுத்தவும்", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "நாடுகள்", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "தனிப்பயன் வேறுபாட்டெல்லை", "label.dashboard": "முகப்பு", "label.data": "Data", + "label.date": "Date", "label.date-range": "தேதி வரம்பு", + "label.day": "Day", "label.default-date-range": "இயல்புநிலை தேதி வரம்பு", "label.delete": "அழி", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "வலைத்தளத்தை நீக்கு", + "label.description": "Description", "label.desktop": "மேசை கணினி", "label.details": "Details", + "label.device": "Device", "label.devices": "சாதனங்கள்", "label.dismiss": "நீக்கு", + "label.does-not-contain": "Does not contain", "label.domain": "கள முகவரி", + "label.dropoff": "Dropoff", "label.edit": "திருத்துதல்", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "கள முகவரியை பகிரலாம்", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "நிகழ்வுகள்", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "ஒருங்கிணைந்த", "label.filter-raw": "மூல", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "முந்தைய {x} மணி", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "உள்நுழைய", "label.logout": "வெளியேறு", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "கைபேசி", "label.more": "மேலும்", + "label.my-websites": "My websites", "label.name": "பெயர்", "label.new-password": "புதிய கடவுச்சொல்", "label.none": "None", - "label.operating-systems": "இயக்க முறைமைகள்", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "பக்க காட்சிகள்", + "label.pageTitle": "Page title", "label.pages": "பக்கங்கள்", "label.password": "கடவுச்சொல்", "label.powered-by": "{name} ஆல் இயக்கப்படுகிறது", "label.profile": "சுயவிவரம்", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "தற்போதைய", + "label.referrer": "Referrer", "label.referrers": "குறிப்பிடுவோர்", "label.refresh": "புதுப்பிப்பு", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "தேவையானவை", "label.reset": "மீட்டமை", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "சேமி", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "அமைப்புகள்", "label.share-url": "வலைத்தள களத்தைப் பகிரவும்", "label.single-day": "ஒரு நாள்", + "label.sum": "Sum", "label.tablet": "கையடக்க கணினி", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "இந்த மாதம்", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "இன்று", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "கண்காணிப்பு குறியீடு", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "தனிப்பட்ட பார்வையாளர்கள்", "label.unknown": "தெரியாத", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "பயனர்பெயர்", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "விபரங்களை பார்", + "label.view-only": "View only", "label.views": "பார்வைகள்", "label.visitors": "பார்வையாளர்கள்", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "வலைத்தளங்கள்", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} தற்போதைய {x, plural, one {ஒன்று} other {மற்ற}}", "message.confirm-delete": "நீங்கள் நிச்சயமாக {target} நீக்க விரும்புகிறீர்களா?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "வலைத்தளத்தை நீக்கு", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்.", "message.error": "ஏதோ தவறு நடந்துவிட்டது.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "தவறான பயனர்பெயர் / கடவுச்சொல்.", "message.invalid-domain": "தவறான கள முகவரி", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "தரவு எதுவும் கிடைக்கவில்லை.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "இருக்கடவுச்சொல் பொருந்தவில்லை", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "உங்களிடம் எந்த வலைத்தளங்களும் கட்டமைக்கப்படவில்லை.", "message.page-not-found": "பக்கம் கிடைக்கவில்லை.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "வெற்றிகரமாக சேமிக்கப்பட்டது.", "message.share-url": "{target} இது பொதுவில் பகிரும் வலைத்தள முகவரி.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "கண்காணிப்பு குறியீடு", "message.user-deleted": "User deleted.", - "message.visitor-log": "{country}வில் இருந்து பார்வையாளர் {browser} ஐ {os} {device}லில் பயன்படுத்துகிறார்", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "உங்களிடம் எந்த வலைத்தளங்களும் கட்டமைக்கப்படவில்லை.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "{country}வில் இருந்து பார்வையாளர் {browser} ஐ {os} {device}லில் பயன்படுத்துகிறார்" } diff --git a/lang/th-TH.json b/src/lang/th-TH.json similarity index 73% rename from lang/th-TH.json rename to src/lang/th-TH.json index d71f4633..43f2f758 100644 --- a/lang/th-TH.json +++ b/src/lang/th-TH.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "การกระทำ", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "เพิ่มเว็บไซต์", "label.admin": "ผู้ดูแลระบบ", + "label.after": "After", "label.all": "ทั้งหมด", "label.all-time": "ทุกช่วงเวลา", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "ระยะเวลาเข้าชมเฉลี่ย", "label.back": "ย้อนกลับ", + "label.before": "Before", "label.bounce-rate": "อัตราตีกลับ", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "เบราว์เซอร์", "label.cancel": "ยกเลิก", "label.change-password": "เปลี่ยนรหัสผ่าน", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "ยืนยันรหัสผ่าน", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "ประเทศ", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "กำหนดช่วงเวลา", "label.dashboard": "แดชบอร์ด", "label.data": "Data", + "label.date": "Date", "label.date-range": "ตั้งแต่วันที่", + "label.day": "Day", "label.default-date-range": "ช่วงเวลา", "label.delete": "ลบ", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "ลบเว็บไซต์", + "label.description": "Description", "label.desktop": "เดสก์ท็อป", "label.details": "Details", + "label.device": "Device", "label.devices": "อุปกรณ์", "label.dismiss": "ยกเลิก", + "label.does-not-contain": "Does not contain", "label.domain": "โดเมน", + "label.dropoff": "Dropoff", "label.edit": "แก้ไข", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "เปิดใช้งานการแชร์ลิงก์", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "เหตุการณ์", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "ข้อมูลรวม", "label.filter-raw": "ข้อมูลดิบ", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "ภาษา", @@ -52,46 +83,64 @@ "label.last-hours": "{x} ชั่วโมงที่ผ่านมา", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "เข้าสู่ระบบ", "label.logout": "ออกจากระบบ", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "โทรศัพท์มือถือ", "label.more": "เพิ่มเติม", + "label.my-websites": "My websites", "label.name": "ชื่อ", "label.new-password": "รหัสผ่านใหม่", "label.none": "ไม่ได้กำหนด", - "label.operating-systems": "ระบบปฏิบัติการ", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "เจ้าของ", + "label.page-of": "Page {current} of {total}", "label.page-views": "การเข้าชม", + "label.pageTitle": "Page title", "label.pages": "หน้าเพจ", "label.password": "รหัสผ่าน", "label.powered-by": "ขับเคลื่อนโดย {name}", "label.profile": "โปรไฟล์", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "เรียลไทม์", + "label.referrer": "Referrer", "label.referrers": "แหล่งที่มา", "label.refresh": "รีเฟรช", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "ต้องการ", "label.reset": "รีเซต", "label.reset-website": "รีเซตข้อมูลสถิติ", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "บันทึก", "label.screens": "ขนาดหน้าจอ", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "ตั้งค่า", "label.share-url": "แชร์ลิงก์", "label.single-day": "วันที่", + "label.sum": "Sum", "label.tablet": "แท็บเล็ต", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "ธีม", "label.this-month": "เดือนปัจจุบัน", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "วันนี้", "label.toggle-charts": "เปิด/ปิดแผนภูมิ", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "โค้ดสำหรับใช้ติดตาม", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "ผู้เข้าชม", "label.unknown": "ไม่รู้จัก", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "ชื่อผู้ใช้", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "แสดงรายละเอียด", + "label.view-only": "View only", "label.views": "การเข้าชม", "label.visitors": "ผู้เข้าชม", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "เว็บไซต์", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "มีผู้ใช้งาน {x} {x, plural, one {คนในขณะนี้} other {คนในขณะนี้}}", "message.confirm-delete": "คุณแน่ใจหรือไม่ว่าต้องการลบ {target} ?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "คุณแน่ใจหรือไม่ว่าต้องการรีเซตข้อมูลสถิติของ {target} ?", - "message.delete-website": "ลบเว็บไซต์", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ.", "message.error": "เกิดข้อผิดพลาด.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง.", "message.invalid-domain": "โดเมนไม่ถูกต้อง", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "ไม่มีข้อมูล.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "รหัสผ่านไม่ตรงกัน", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "คุณยังไม่ได้ตั้งค่าเว็บไซต์ใด ๆ ไว้.", "message.page-not-found": "ไม่พบหน้านี้.", - "message.reset-website": "รีเซตข้อมูลสถิติ", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "สถิติทั้งหมดสำหรับเว็บไซต์นี้จะถูกลบออก แต่โค้ดสำหรับใช้ติดตามของคุณจะยังคงอยู่เหมือนเดิม.", "message.saved": "บันทึกข้อมูลเรียบร้อย.", "message.share-url": "นี่คือลิงก์ที่แชร์แบบสาธารณะสำหรับ {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "โค้ดสำหรับใช้ติดตาม", "message.user-deleted": "User deleted.", - "message.visitor-log": "ผู้เข้าชมจาก {country} กำลังใช้งานผ่าน {browser} บน {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "คุณยังไม่ได้ตั้งค่าเว็บไซต์ใด ๆ ไว้.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "ผู้เข้าชมจาก {country} กำลังใช้งานผ่าน {browser} บน {os} {device}" } diff --git a/lang/tr-TR.json b/src/lang/tr-TR.json similarity index 66% rename from lang/tr-TR.json rename to src/lang/tr-TR.json index 97556349..0ec10e0b 100644 --- a/lang/tr-TR.json +++ b/src/lang/tr-TR.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Hareketler", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Web sitesi ekle", "label.admin": "Yönetici", + "label.after": "After", "label.all": "Tümü", "label.all-time": "All time", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Ortalama ziyaret süresi", "label.back": "Geri", + "label.before": "Before", "label.bounce-rate": "Çıkma oranı", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Tarayıcılar", "label.cancel": "İptal", "label.change-password": "Şifre değiştir", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Parolayı onayla", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Ülkeler", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Özelleştirilmiş aralık", "label.dashboard": "Kontrol Paneli", "label.data": "Data", + "label.date": "Date", "label.date-range": "Tarih aralığı", + "label.day": "Day", "label.default-date-range": "Varsayılan tarih aralığı", "label.delete": "Sil", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Web sitesini sil", + "label.description": "Description", "label.desktop": "Masaüstü", "label.details": "Details", + "label.device": "Device", "label.devices": "Cihazlar", "label.dismiss": "Reddet", + "label.does-not-contain": "Does not contain", "label.domain": "Alan adı", + "label.dropoff": "Dropoff", "label.edit": "Düzenle", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Anonim paylaşım URL'i aktif", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Olaylar", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Birleşik", "label.filter-raw": "Ham", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Son {x} saat", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Giriş Yap", "label.logout": "Çıkış Yap", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Mobil Cihaz", "label.more": "Detaylı göster", + "label.my-websites": "My websites", "label.name": "İsim", "label.new-password": "Yeni parola", "label.none": "None", - "label.operating-systems": "İşletim sistemi", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Owner", + "label.page-of": "Page {current} of {total}", "label.page-views": "Sayfa görünümü", + "label.pageTitle": "Page title", "label.pages": "Sayfalar", "label.password": "Parola", "label.powered-by": "Sağlayıcı: {name}", "label.profile": "Profil", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Gerçek Zamanlı", + "label.referrer": "Referrer", "label.referrers": "Yönlendirenler", "label.refresh": "Yenile", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Zorunlu alan", "label.reset": "Sıfırla", "label.reset-website": "Reset statistics", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Kaydet", "label.screens": "Ekranlar", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Ayarlar", "label.share-url": "Paylaşım adresi", "label.single-day": "Tekil gün", + "label.sum": "Sum", "label.tablet": "Tablet", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Bu ay", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Bugün", "label.toggle-charts": "Toggle charts", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "İzleme kodu", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Tekil kullanıcı", "label.unknown": "Bilinmeyen", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Kullanıcı adı", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Detayı incele", + "label.view-only": "View only", "label.views": "Görüntüleme", "label.visitors": "Ziyaretçi", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Web siteleri", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} aktif ziyaretçi", "message.confirm-delete": "{target} kaydını silmek istediğinizden emin misiniz?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Are your sure you want to reset {target}'s statistics?", - "message.delete-website": "Web sitesini sil", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "İlişkili tüm veriler de silinecektir.", "message.error": "Bir şeyler ters gitti!", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Hatalı kullanıcı adı ya da parola.", "message.invalid-domain": "Geçersiz alan adı", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Henüz hiç veri yok.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Parolalar uyuşmuyor", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Henüz hiç web sitesi tanımlamadınız", "message.page-not-found": "Sayfa bulunamadı.", - "message.reset-website": "Reset statistics", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "All statistics for this website will be deleted, but your tracking code will remain intact.", "message.saved": "Başarıyla kaydedildi.", "message.share-url": "{target} için kullanılabilir anonim paylaşım adresidir.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "İzleme kodu", "message.user-deleted": "User deleted.", - "message.visitor-log": "Yeni ziyaretçi: {country}, {os}, {device}, {browser}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Henüz hiç web sitesi tanımlamadınız", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Yeni ziyaretçi: {country}, {os}, {device}, {browser}" } diff --git a/lang/uk-UA.json b/src/lang/uk-UA.json similarity index 70% rename from lang/uk-UA.json rename to src/lang/uk-UA.json index 413f2dad..89079eff 100644 --- a/lang/uk-UA.json +++ b/src/lang/uk-UA.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Дії", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Додати сайт", "label.admin": "Адміністратор", + "label.after": "After", "label.all": "Всі", "label.all-time": "Весь час", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Середній час візиту", "label.back": "Назад", + "label.before": "Before", "label.bounce-rate": "Показник відмов", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Браузери", "label.cancel": "Відмінити", "label.change-password": "Змінити пароль", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Підтвердити пароль", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Країни", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Довільний період", "label.dashboard": "Інформаційна панель", "label.data": "Data", + "label.date": "Date", "label.date-range": "Діапазон дат", + "label.day": "Day", "label.default-date-range": "Діапазон дат за замовчуванням", "label.delete": "Видалити", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Видалити сайт", + "label.description": "Description", "label.desktop": "Настільний ПК", "label.details": "Details", + "label.device": "Device", "label.devices": "Пристрої", "label.dismiss": "Відхилити", + "label.does-not-contain": "Does not contain", "label.domain": "Домен", + "label.dropoff": "Dropoff", "label.edit": "Редагувати", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Дозволити ділитися посиланням", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Події", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Об'єднані", "label.filter-raw": "Сирі дані", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "Останні {x} годин", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Увійти", "label.logout": "Вийти", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Мобільний", "label.more": "Більше", + "label.my-websites": "My websites", "label.name": "Ім'я", "label.new-password": "Новий пароль", "label.none": "None", - "label.operating-systems": "Операційні системи", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Власник", + "label.page-of": "Page {current} of {total}", "label.page-views": "Перегляди сторінок", + "label.pageTitle": "Page title", "label.pages": "Сторінки", "label.password": "Пароль", "label.powered-by": "На базі {name}", "label.profile": "Профіль", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "У реальному часі", + "label.referrer": "Referrer", "label.referrers": "Джерела", "label.refresh": "Оновити", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Обов'язкове", "label.reset": "Скинути", "label.reset-website": "Скинути статистику сайту", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Зберегти", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Налаштування", "label.share-url": "Поділитися посилання", "label.single-day": "Один день", + "label.sum": "Sum", "label.tablet": "Планшет", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "Цього місяця", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Сьогодні", "label.toggle-charts": "Переключити графіки", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Код для відслідковування", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Унікальні відвідувачі", "label.unknown": "Невідомо", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Ім'я користувача", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Переглянути деталі", + "label.view-only": "View only", "label.views": "Перегляди", "label.visitors": "Відвідувачі", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Сайти", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} поточних відвідувачів", "message.confirm-delete": "Ви впевнені, що бажаєте видалити {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Ви впевнені, що бажаєте скинути статистику для {target}?", - "message.delete-website": "Видалити сайт", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Усі пов'язані дані будуть видалені також.", "message.error": "Щось пішло не так.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Невірне ім'я користувача або пароль.", "message.invalid-domain": "Некоректний домен", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Немає даних.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Паролі не співпадають", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "У вас немає налаштованих сайтів.", "message.page-not-found": "Сторінку не знайдено.", - "message.reset-website": "Скинути статистику сайту", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Вся статистика для цього сайту буде видалена, проте код відслідковування буде продовжувати працювати.", "message.saved": "Збережено успішно.", "message.share-url": "Це публічне посилання для {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Код для відслідковування", "message.user-deleted": "User deleted.", - "message.visitor-log": "Відвідувач з {country} використовуючи {browser} на {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "У вас немає налаштованих сайтів.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Відвідувач з {country} використовуючи {browser} на {os} {device}" } diff --git a/lang/ur-PK.json b/src/lang/ur-PK.json similarity index 69% rename from lang/ur-PK.json rename to src/lang/ur-PK.json index d206de64..4d585dcb 100644 --- a/lang/ur-PK.json +++ b/src/lang/ur-PK.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "اعمال", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "ویب سائٹ کا اضافہ کریں", "label.admin": "منتظم", + "label.after": "After", "label.all": "تمام", "label.all-time": "تمام وقت", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "وزٹ کا اوسط وقت", "label.back": "پیچھے", + "label.before": "Before", "label.bounce-rate": "اچھال کی شرح", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "براؤزرز", "label.cancel": "منسوخ", "label.change-password": "پاس ورڈ تبدیل کریں", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "پاس ورڈ کی تصدیق کریں", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "ممالک", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "اپنی مرضی کی حد", "label.dashboard": "ڈیش بورڈ", "label.data": "Data", + "label.date": "Date", "label.date-range": "تاریخ کی حد", + "label.day": "Day", "label.default-date-range": "پہلے سے طے شدہ تاریخ کی حد", "label.delete": "حذف کریں", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "ویب سائٹ مٹایں", + "label.description": "Description", "label.desktop": "ڈیسک ٹاپ", "label.details": "Details", + "label.device": "Device", "label.devices": "آلات", "label.dismiss": "مسترد کریں", + "label.does-not-contain": "Does not contain", "label.domain": "ڈومین", + "label.dropoff": "Dropoff", "label.edit": "ترمیم", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "شیئر یو آر ایل کو فعال کریں", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "واقعات", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "مشترکہ", "label.filter-raw": "خام", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "پچھلے {x} گھنٹے", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "لاگ ان", "label.logout": "لاگ آوٹ", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "موبائل", "label.more": "مزید", + "label.my-websites": "My websites", "label.name": "نام", "label.new-password": "نیا پاس ورڈ", "label.none": "None", - "label.operating-systems": "آپریٹنگ سسٹمز", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "مالک", + "label.page-of": "Page {current} of {total}", "label.page-views": "صفحہ کے نظارے", + "label.pageTitle": "Page title", "label.pages": "صفحات", "label.password": "پاس ورڈ", "label.powered-by": "تقویت یافتہ بذریعہ {name}", "label.profile": "پروفائل", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "براہ راست", + "label.referrer": "Referrer", "label.referrers": "بھیجنے والے", "label.refresh": "تازہ دم کریں", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "درکار ہے", "label.reset": "دوبارہ ترتیب دیں", "label.reset-website": "اعدادوشمار کو دوبارہ ترتیب دیں", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "محفوظ کریں", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "ترتیبات", "label.share-url": "URL کا اشتراک کریں", "label.single-day": "ایک دن", + "label.sum": "Sum", "label.tablet": "ٹیبلیٹ", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Theme", "label.this-month": "اس مہینے", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "آج", "label.toggle-charts": "چارٹ تبدیل کریں", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "ٹریکنگ کوڈ", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "منفرد زائرین", "label.unknown": "نامعلوم", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "صارف نام", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "تفصیلات دیکھیں", + "label.view-only": "View only", "label.views": "مناظر", "label.visitors": "زائرین", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "ویب سائٹس", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} موجودہ {x, plural, one {زائر} other {زائرین}}", "message.confirm-delete": "کیا آپ واقعی {target} کو حذف کرنا چاہتے ہیں؟", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "کیا آپ واقعی {target} کے اعدادوشمار کو دوبارہ ترتیب دینا چاہتے ہیں؟", - "message.delete-website": "ویب سائٹ مٹایں", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔", "message.error": "کچھ غلط ہو گیا.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "غلط صارف نام/پاس ورڈ۔", "message.invalid-domain": "غلط ڈومین", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "مواد موجود نہیں ہے.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "پاس ورڈز مماثل نہیں ہیں", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "آپ کے پاس کوئی ویب سائٹ کنفیگر نہیں ہے۔", "message.page-not-found": "صفحہ نہیں ملا.", - "message.reset-website": "اعدادوشمار کو دوبارہ ترتیب دیں", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "اس ویب سائٹ کے تمام اعدادوشمار کو حذف کر دیا جائے گا، لیکن آپ کا ٹریکنگ کوڈ برقرار رہے گا۔", "message.saved": "کامیابی سے محفوظ ہو گیا۔", "message.share-url": "یہ {target} کے لیے عوامی طور پر اشتراک کردہ URL ہے۔", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "ٹریکنگ کوڈ", "message.user-deleted": "User deleted.", - "message.visitor-log": "{os} {device} پر {browser} کا استعمال کرتے ہوئے {country} سے آنے والا", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "آپ کے پاس کوئی ویب سائٹ کنفیگر نہیں ہے۔", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "{os} {device} پر {browser} کا استعمال کرتے ہوئے {country} سے آنے والا" } diff --git a/lang/vi-VN.json b/src/lang/vi-VN.json similarity index 68% rename from lang/vi-VN.json rename to src/lang/vi-VN.json index fe27ce4d..e9bce2d3 100644 --- a/lang/vi-VN.json +++ b/src/lang/vi-VN.json @@ -2,23 +2,34 @@ "label.access-code": "Access code", "label.actions": "Hành động", "label.activity-log": "Activity log", + "label.add": "Add", + "label.add-description": "Add description", "label.add-website": "Thêm website", "label.admin": "Quản trị", + "label.after": "After", "label.all": "Tất cả", "label.all-time": "Toàn thời gian", "label.analytics": "Analytics", + "label.average": "Average", "label.average-visit-time": "Thời gian truy cập trung bình", "label.back": "Quay về", + "label.before": "Before", "label.bounce-rate": "Tỷ lệ thoát trang", + "label.breakdown": "Breakdown", + "label.browser": "Browser", "label.browsers": "Trình duyệt", "label.cancel": "Huỷ bỏ", "label.change-password": "Đổi mật khẩu", "label.cities": "Cities", + "label.city": "City", "label.clear-all": "Clear all", "label.confirm": "Confirm", "label.confirm-password": "Xác nhận mật khẩu", + "label.contains": "Contains", "label.continue": "Continue", "label.countries": "Quốc gia", + "label.country": "Country", + "label.create-report": "Create report", "label.create-team": "Create team", "label.create-user": "Create user", "label.created": "Created", @@ -26,23 +37,43 @@ "label.custom-range": "Phạm vi ngày tuỳ chọn", "label.dashboard": "Bảng điều khiển", "label.data": "Data", + "label.date": "Date", "label.date-range": "Phạm vi ngày", + "label.day": "Day", "label.default-date-range": "Khoảng thời gian mặc định", "label.delete": "Xoá", "label.delete-team": "Delete team", "label.delete-user": "Delete user", "label.delete-website": "Xóa website", + "label.description": "Description", "label.desktop": "Máy bàn", "label.details": "Details", + "label.device": "Device", "label.devices": "Thiết bị", "label.dismiss": "Loại trừ", + "label.does-not-contain": "Does not contain", "label.domain": "Tên miền", + "label.dropoff": "Dropoff", "label.edit": "Chỉnh sửa", "label.edit-dashboard": "Edit dashboard", "label.enable-share-url": "Bật khả năng chia sẻ URL", + "label.event": "Event", + "label.event-data": "Event data", "label.events": "Sự kiện", + "label.false": "False", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "Kết hợp", "label.filter-raw": "Gốc", + "label.filters": "Filters", + "label.funnel": "Funnel", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "Insights", + "label.is": "Is", + "label.is-not": "Is not", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "Join", "label.join-team": "Join team", "label.language": "Language", @@ -52,46 +83,64 @@ "label.last-hours": "{x} giờ gần nhất", "label.leave": "Leave", "label.leave-team": "Leave team", + "label.less-than": "Less than", + "label.less-than-equals": "Less than or equals", "label.login": "Đăng nhập", "label.logout": "Đăng xuất", + "label.max": "Max", "label.members": "Members", + "label.min": "Min", "label.mobile": "Di động", "label.more": "Thêm", + "label.my-websites": "My websites", "label.name": "Tên", "label.new-password": "Mật khẩu mới", "label.none": "None", - "label.operating-systems": "Hệ điều hành", + "label.os": "OS", + "label.overview": "Overview", "label.owner": "Chủ sở hữu", + "label.page-of": "Page {current} of {total}", "label.page-views": "Lượt xem", + "label.pageTitle": "Page title", "label.pages": "Trang", "label.password": "Mật khẩu", "label.powered-by": "Bản quyền thuộc về {name}", "label.profile": "Hồ sơ", "label.queries": "Queries", + "label.query": "Query", "label.query-parameters": "Query parameters", "label.realtime": "Thời gian thực", + "label.referrer": "Referrer", "label.referrers": "Liên kết giới thiệu", "label.refresh": "Làm mới", "label.regenerate": "Regenerate", + "label.region": "Region", "label.regions": "Regions", "label.remove": "Remove", + "label.reports": "Reports", "label.required": "Yêu cầu", "label.reset": "Tái thiết lập", "label.reset-website": "Tái thiết lập thống kê", + "label.retention": "Retention", "label.role": "Role", + "label.run-query": "Run query", "label.save": "Lưu", "label.screens": "Screens", + "label.select-date": "Select date", "label.select-website": "Select website", "label.sessions": "Sessions", "label.settings": "Cài đặt", "label.share-url": "Chia sẻ URL", "label.single-day": "Trong ngày", + "label.sum": "Sum", "label.tablet": "Máy tính bảng", "label.team": "Team", "label.team-guest": "Team guest", "label.team-id": "Team ID", "label.team-member": "Team member", + "label.team-name": "Team name", "label.team-owner": "Team owner", + "label.team-websites": "Team websites", "label.teams": "Teams", "label.theme": "Giao diện", "label.this-month": "Tháng này", @@ -101,24 +150,37 @@ "label.title": "Title", "label.today": "Hôm nay", "label.toggle-charts": "Bật/tắt biểu đồ", + "label.total": "Total", + "label.total-records": "Total records", "label.tracking-code": "Mã theo dõi", + "label.true": "True", + "label.type": "Type", + "label.unique": "Unique", "label.unique-visitors": "Khách truy cập một lần", "label.unknown": "Không rõ", + "label.untitled": "Untitled", + "label.url": "URL", + "label.urls": "URLs", "label.user": "User", "label.username": "Tên đăng nhập", "label.users": "Users", + "label.value": "Value", "label.view": "View", "label.view-details": "Xem chi tiết", + "label.view-only": "View only", "label.views": "Xem", "label.visitors": "Khách", + "label.website": "Website", "label.website-id": "Website ID", "label.websites": "Websites", + "label.window": "Window", "label.yesterday": "Yesterday", "message.active-users": "{x} hiện tại {x, plural, one {một} other {trên}}", "message.confirm-delete": "Bạn có chắc chắn muốn xoá {target}?", "message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-reset": "Bạn có chắc chắn muốn tái thiết lập thống kê {target}?", - "message.delete-website": "Xóa website", + "message.delete-account": "To delete this account, type {confirmation} in the box below to confirm.", + "message.delete-website": "To delete this website, type {confirmation} in the box below to confirm.", "message.delete-website-warning": "Tất cả các dữ liệu liên quan cũng sẽ bị xoá.", "message.error": "Đã xảy ra lỗi.", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "Sai tên đăng nhập/mật khẩu.", "message.invalid-domain": "Tên miền không hợp lệ", "message.min-password-length": "Minimum length of {n} characters", + "message.new-version-available": "A new version of Umami {version} is available!", "message.no-data-available": "Không có dữ liệu.", + "message.no-event-data": "No event data is available.", "message.no-match-password": "Mật khẩu không đồng nhất", + "message.no-results-found": "No results were found.", + "message.no-team-websites": "This team does not have any websites.", "message.no-teams": "You have not created any teams.", "message.no-users": "There are no users.", + "message.no-websites-configured": "Bạn chưa có bất cứ website nào.", "message.page-not-found": "Trang không tìm thấy.", - "message.reset-website": "Tái thiết lập thống kê", + "message.reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "message.reset-website-warning": "Tất cả số liệu thống kê của website này sẽ bị xoá, nhưng mã theo dõi sẽ vẫn giữ nguyên.", "message.saved": "Đã lưu thành công.", "message.share-url": "Đây là đường dẫn URL cho {target}.", "message.team-already-member": "You are already a member of the team.", "message.team-not-found": "Team not found.", + "message.team-websites-info": "Websites can be viewed by anyone on the team.", "message.tracking-code": "Mã theo dõi", "message.user-deleted": "User deleted.", - "message.visitor-log": "Khách từ {country} đang dùng {browser} trên {os} {device}", - "messages.no-team-websites": "This team does not have any websites.", - "messages.no-websites-configured": "Bạn chưa có bất cứ website nào.", - "messages.team-websites-info": "Websites can be viewed by anyone on the team." + "message.visitor-log": "Khách từ {country} đang dùng {browser} trên {os} {device}" } diff --git a/lang/zh-CN.json b/src/lang/zh-CN.json similarity index 64% rename from lang/zh-CN.json rename to src/lang/zh-CN.json index 1aba3988..91043dac 100644 --- a/lang/zh-CN.json +++ b/src/lang/zh-CN.json @@ -2,23 +2,34 @@ "label.access-code": "访问代码", "label.actions": "用户行为", "label.activity-log": "活动日志", + "label.add": "添加", + "label.add-description": "添加描述", "label.add-website": "添加网站", "label.admin": "管理员", + "label.after": "之后", "label.all": "所有", "label.all-time": "所有时间段", "label.analytics": "分析", + "label.average": "平均", "label.average-visit-time": "平均访问时间", "label.back": "返回", + "label.before": "之前", "label.bounce-rate": "跳出率", + "label.breakdown": "故障", + "label.browser": "Browser", "label.browsers": "浏览器", "label.cancel": "取消", "label.change-password": "更新密码", "label.cities": "市/县", + "label.city": "City", "label.clear-all": "清除全部", "label.confirm": "确认", "label.confirm-password": "确认密码", + "label.contains": "包含", "label.continue": "继续", "label.countries": "国家/地区", + "label.country": "Country", + "label.create-report": "创建报告", "label.create-team": "创建团队", "label.create-user": "创建用户", "label.created": "已创建", @@ -26,23 +37,43 @@ "label.custom-range": "自定义时间段", "label.dashboard": "仪表板", "label.data": "统计数据", + "label.date": "Date", "label.date-range": "时间段", + "label.day": "Day", "label.default-date-range": "默认时间段", "label.delete": "删除", "label.delete-team": "删除团队", "label.delete-user": "删除用户", "label.delete-website": "删除网站", + "label.description": "描述", "label.desktop": "台式机", "label.details": "详细信息", + "label.device": "Device", "label.devices": "设备", "label.dismiss": "关闭", + "label.does-not-contain": "不包含", "label.domain": "域名", + "label.dropoff": "丢弃", "label.edit": "编辑", "label.edit-dashboard": "编辑仪表板", "label.enable-share-url": "启用共享链接", + "label.event": "事件", + "label.event-data": "事件数据", "label.events": "行为类别", + "label.false": "否", + "label.field": "Field", + "label.fields": "Fields", "label.filter-combined": "合并", "label.filter-raw": "原始", + "label.filters": "筛选", + "label.funnel": "分析", + "label.greater-than": "Greater than", + "label.greater-than-equals": "Greater than or equals", + "label.insights": "见解", + "label.is": "等于", + "label.is-not": "不等于", + "label.is-not-set": "Is not set", + "label.is-set": "Is set", "label.join": "加入", "label.join-team": "加入团队", "label.language": "语言", @@ -52,46 +83,64 @@ "label.last-hours": "最近 {x} 小时", "label.leave": "离开", "label.leave-team": "离开团队", + "label.less-than": "少于", + "label.less-than-equals": "少于等于", "label.login": "登录", "label.logout": "退出", + "label.max": "最大", "label.members": "成员", + "label.min": "最小", "label.mobile": "手机", "label.more": "更多", + "label.my-websites": "My websites", "label.name": "名字", "label.new-password": "新密码", "label.none": "无", - "label.operating-systems": "操作系统", + "label.os": "OS", + "label.overview": "概览", "label.owner": "所有者", + "label.page-of": "Page {current} of {total}", "label.page-views": "页面浏览量", + "label.pageTitle": "Page title", "label.pages": "网页", "label.password": "密码", "label.powered-by": "由 {name} 提供支持", "label.profile": "个人资料", "label.queries": "查询", + "label.query": "查询", "label.query-parameters": "查询参数", "label.realtime": "实时", + "label.referrer": "Referrer", "label.referrers": "来源域名", "label.refresh": "刷新", "label.regenerate": "重新生成", + "label.region": "Region", "label.regions": "州/省", "label.remove": "移除", + "label.reports": "报告", "label.required": "必填", "label.reset": "重置", "label.reset-website": "重置统计数据", + "label.retention": "Retention", "label.role": "角色", + "label.run-query": "查询", "label.save": "保存", "label.screens": "屏幕尺寸", + "label.select-date": "选择数据", "label.select-website": "选择网站", "label.sessions": "会话", "label.settings": "设置", "label.share-url": "共享链接", "label.single-day": "单日", + "label.sum": "总和", "label.tablet": "平板", "label.team": "团队", "label.team-guest": "团队访客", "label.team-id": "团队 ID", "label.team-member": "团队成员", + "label.team-name": "Team name", "label.team-owner": "团队所有者", + "label.team-websites": "Team websites", "label.teams": "团队", "label.theme": "主题", "label.this-month": "本月", @@ -101,24 +150,37 @@ "label.title": "标题", "label.today": "今天", "label.toggle-charts": "切换图表", + "label.total": "总数", + "label.total-records": "总记录数", "label.tracking-code": "跟踪代码", + "label.true": "是", + "label.type": "类型", + "label.unique": "Unique", "label.unique-visitors": "独立访客", "label.unknown": "未知", + "label.untitled": "未命名", + "label.url": "URL", + "label.urls": "URLs", "label.user": "用户", "label.username": "用户名", "label.users": "用户", + "label.value": "值", "label.view": "查看", "label.view-details": "查看更多", + "label.view-only": "View only", "label.views": "浏览量", "label.visitors": "访客", + "label.website": "网站", "label.website-id": "网站 ID", "label.websites": "网站", + "label.window": "窗口", "label.yesterday": "昨天", "message.active-users": "当前在线 {x} 人", "message.confirm-delete": "你确定要删除 {target} 吗?", "message.confirm-leave": "你确定要离开 {target} 吗?", "message.confirm-reset": "您确定要重置 {target} 的数据吗?", - "message.delete-website": "删除网站", + "message.delete-account": "确定删除该账户, 请在下面的输入框中输入 {confirmation} 进行二次确认。", + "message.delete-website": "确定删除该网站, 请在下面的输入框中输入 {confirmation} 进行二次确认。", "message.delete-website-warning": "所有相关数据将会被删除。", "message.error": "出现错误。", "message.event-log": "{event} on {url}", @@ -126,21 +188,24 @@ "message.incorrect-username-password": "用户名或密码不正确。", "message.invalid-domain": "无效域名", "message.min-password-length": "密码最短长度为 {n} 个字符", + "message.new-version-available": "Umami的新版本{version}已推出!", "message.no-data-available": "无可用数据。", + "message.no-event-data": "无可用事件。", "message.no-match-password": "密码不一致", + "message.no-results-found": "没有找到任何结果。", + "message.no-team-websites": "这个团队没有任何网站。", "message.no-teams": "你还没有创建任何团队。", "message.no-users": "没有任何用户。", + "message.no-websites-configured": "你还没有设置任何网站。", "message.page-not-found": "网页未找到。", - "message.reset-website": "重置统计数据", + "message.reset-website": "如果确定重置该网站, 请在下面的输入框中输入 {confirmation} 进行二次确认。", "message.reset-website-warning": "本网站的所有统计数据将被删除,但您的跟踪代码将保持不变。", "message.saved": "保存成功。", "message.share-url": "这是 {target} 的共享链接。", "message.team-already-member": "你已经是该团队的成员。", "message.team-not-found": "未找到团队。", + "message.team-websites-info": "团队中的任何人都可查看网站。", "message.tracking-code": "跟踪代码", - "message.user-deleted": "User detected.", - "message.visitor-log": "来自{country}的访客在搭载 {os} 的{device}上使用 {browser} 浏览器进行访问。", - "messages.no-team-websites": "这个团队没有任何网站。", - "messages.no-websites-configured": "你还没有设置任何网站。", - "messages.team-websites-info": "团队中的任何人都可查看网站。" + "message.user-deleted": "用户已删除。", + "message.visitor-log": "来自{country}的访客在搭载 {os} 的{device}上使用 {browser} 浏览器进行访问。" } diff --git a/src/lang/zh-TW.json b/src/lang/zh-TW.json new file mode 100644 index 00000000..05b61c80 --- /dev/null +++ b/src/lang/zh-TW.json @@ -0,0 +1,211 @@ +{ + "label.access-code": "存取碼", + "label.actions": "行動", + "label.activity-log": "活動日誌", + "label.add": "新增", + "label.add-description": "新增描述", + "label.add-website": "新增網站", + "label.admin": "管理員", + "label.after": "之後", + "label.all": "全部", + "label.all-time": "所有時間", + "label.analytics": "分析", + "label.average": "平均", + "label.average-visit-time": "平均造訪時間", + "label.back": "返回", + "label.before": "之前", + "label.bounce-rate": "跳出率", + "label.breakdown": "分解", + "label.browser": "瀏覽器", + "label.browsers": "瀏覽器", + "label.cancel": "取消", + "label.change-password": "更改密碼", + "label.cities": "城市", + "label.city": "城市", + "label.clear-all": "全部清除", + "label.confirm": "確認", + "label.confirm-password": "確認密碼", + "label.contains": "包含", + "label.continue": "繼續", + "label.countries": "國家", + "label.country": "國家", + "label.create-report": "建立報告", + "label.create-team": "建立團隊", + "label.create-user": "建立使用者", + "label.created": "已建立", + "label.current-password": "目前密碼", + "label.custom-range": "自訂範圍", + "label.dashboard": "儀表板", + "label.data": "資料", + "label.date": "日期", + "label.date-range": "日期範圍", + "label.day": "日", + "label.default-date-range": "預設日期範圍", + "label.delete": "刪除", + "label.delete-team": "刪除團隊", + "label.delete-user": "刪除使用者", + "label.delete-website": "刪除網站", + "label.description": "描述", + "label.desktop": "桌上型電腦", + "label.details": "詳細資訊", + "label.device": "裝置", + "label.devices": "裝置", + "label.dismiss": "關閉", + "label.does-not-contain": "不包含", + "label.domain": "網域", + "label.dropoff": "退出", + "label.edit": "編輯", + "label.edit-dashboard": "編輯儀表板", + "label.enable-share-url": "啟用分享網址", + "label.event": "事件", + "label.event-data": "事件資料", + "label.events": "事件", + "label.false": "否", + "label.field": "欄位", + "label.fields": "欄位", + "label.filter-combined": "組合", + "label.filter-raw": "原始", + "label.filters": "篩選器", + "label.funnel": "漏斗", + "label.greater-than": "大於", + "label.greater-than-equals": "大於或等於", + "label.insights": "洞察", + "label.is": "是", + "label.is-not": "不是", + "label.is-not-set": "未設定", + "label.is-set": "已設定", + "label.join": "加入", + "label.join-team": "加入團隊", + "label.language": "語言", + "label.languages": "語言", + "label.laptop": "筆記型電腦", + "label.last-days": "最近 {x} 天", + "label.last-hours": "最近 {x} 小時", + "label.leave": "離開", + "label.leave-team": "離開團隊", + "label.less-than": "小於", + "label.less-than-equals": "小於或等於", + "label.login": "登入", + "label.logout": "登出", + "label.max": "最大", + "label.members": "成員", + "label.min": "最小", + "label.mobile": "行動裝置", + "label.more": "更多", + "label.my-websites": "我的網站", + "label.name": "名稱", + "label.new-password": "新密碼", + "label.none": "無", + "label.os": "作業系統", + "label.overview": "概覽", + "label.owner": "擁有者", + "label.page-of": "頁面 {current} / {total}", + "label.page-views": "頁面瀏覽", + "label.pageTitle": "頁面標題", + "label.pages": "頁面", + "label.password": "密碼", + "label.powered-by": "由 {name} 提供", + "label.profile": "個人資料", + "label.queries": "查詢", + "label.query": "查詢", + "label.query-parameters": "查詢參數", + "label.realtime": "即時", + "label.referrer": "參照來源", + "label.referrers": "參照來源", + "label.refresh": "重新整理", + "label.regenerate": "重新產生", + "label.region": "區域", + "label.regions": "區域", + "label.remove": "移除", + "label.reports": "報告", + "label.required": "必填", + "label.reset": "重設", + "label.reset-website": "重設網站", + "label.retention": "保留", + "label.role": "角色", + "label.run-query": "執行查詢", + "label.save": "儲存", + "label.screens": "螢幕", + "label.select-date": "選擇日期", + "label.select-website": "選擇網站", + "label.sessions": "工作階段", + "label.settings": "設定", + "label.share-url": "分享網址", + "label.single-day": "單日", + "label.sum": "總和", + "label.tablet": "平板", + "label.team": "團隊", + "label.team-guest": "團隊訪客", + "label.team-id": "團隊 ID", + "label.team-member": "團隊成員", + "label.team-name": "團隊名稱", + "label.team-owner": "團隊擁有者", + "label.team-websites": "團隊網站", + "label.teams": "團隊", + "label.theme": "主題", + "label.this-month": "本月", + "label.this-week": "本週", + "label.this-year": "今年", + "label.timezone": "時區", + "label.title": "標題", + "label.today": "今天", + "label.toggle-charts": "切換圖表", + "label.total": "總計", + "label.total-records": "總記錄", + "label.tracking-code": "追蹤代碼", + "label.true": "是", + "label.type": "類型", + "label.unique": "獨立", + "label.unique-visitors": "獨立訪客", + "label.unknown": "未知", + "label.untitled": "無標題", + "label.url": "網址", + "label.urls": "網址", + "label.user": "使用者", + "label.username": "使用者名稱", + "label.users": "使用者", + "label.value": "值", + "label.view": "檢視", + "label.view-details": "檢視詳細資訊", + "label.view-only": "僅供檢視", + "label.views": "檢視", + "label.visitors": "訪客", + "label.website": "網站", + "label.website-id": "網站 ID", + "label.websites": "網站", + "label.window": "視窗", + "label.yesterday": "昨天", + "message.active-users": "目前有 {x} 個活躍的訪客", + "message.confirm-delete": "您確定要刪除 {target} 嗎?", + "message.confirm-leave": "您確定要離開 {target} 嗎?", + "message.confirm-reset": "您確定要重設 {target} 嗎?", + "message.delete-account": "要刪除此帳戶,請在下方的方框中輸入 {confirmation} 以確認。", + "message.delete-website": "要刪除此網站,請在下方的方框中輸入 {confirmation} 以確認。", + "message.delete-website-warning": "所有網站資料將被刪除。", + "message.error": "發生錯誤。", + "message.event-log": "{event} 在 {url}", + "message.go-to-settings": "前往設定", + "message.incorrect-username-password": "使用者名稱和/或密碼不正確。", + "message.invalid-domain": "無效的網域。請不要包含 http/https。", + "message.min-password-length": "最少需要 {n} 個字元", + "message.new-version-available": "Umami {version} 的新版本已經可以使用!", + "message.no-data-available": "沒有可用的資料。", + "message.no-event-data": "沒有可用的事件資料。", + "message.no-match-password": "密碼不一致。", + "message.no-results-found": "找不到結果。", + "message.no-team-websites": "此團隊沒有任何網站。", + "message.no-teams": "您尚未建立任何團隊。", + "message.no-users": "沒有使用者。", + "message.no-websites-configured": "您尚未設定任何網站。", + "message.page-not-found": "找不到頁面", + "message.reset-website": "要重設此網站,請在下方的方框中輸入 {confirmation} 以確認。", + "message.reset-website-warning": "此網站的所有統計將被刪除,但您的設定將保持不變。", + "message.saved": "已儲存。", + "message.share-url": "您的網站統計資料可以在以下網址公開檢視:", + "message.team-already-member": "您已經是團隊的成員。", + "message.team-not-found": "找不到團隊。", + "message.team-websites-info": "團隊的任何成員都可以檢視網站。", + "message.tracking-code": "要追蹤此網站的統計,請將以下代碼放在您的 HTML 的 ... 區段中。", + "message.user-deleted": "使用者已刪除。", + "message.visitor-log": "來自 {country} 的訪客在 {device} 上的 {os} 使用 {browser} 瀏覽。" +} diff --git a/lib/auth.ts b/src/lib/auth.ts similarity index 61% rename from lib/auth.ts rename to src/lib/auth.ts index 2195ad8f..4a42d85d 100644 --- a/lib/auth.ts +++ b/src/lib/auth.ts @@ -1,22 +1,15 @@ -import debug from 'debug'; +import { Report } from '@prisma/client'; import redis from '@umami/redis-client'; -import cache from 'lib/cache'; +import debug from 'debug'; import { PERMISSIONS, ROLE_PERMISSIONS, SHARE_TOKEN_HEADER } from 'lib/constants'; import { secret } from 'lib/crypto'; -import { - createSecureToken, - ensureArray, - getRandomChars, - parseSecureToken, - parseToken, -} from 'next-basics'; -import { getTeamUser, getTeamUserById } from 'queries'; -import { getTeamWebsite, getTeamWebsiteByTeamMemberId } from 'queries/admin/teamWebsite'; -import { validate } from 'uuid'; +import { createSecureToken, ensureArray, getRandomChars, parseToken } from 'next-basics'; +import { findTeamWebsiteByUserId, getTeamUser, getTeamWebsite } from 'queries'; +import { loadWebsite } from './load'; import { Auth } from './types'; -import { loadWebsite } from './query'; const log = debug('umami:auth'); +const cloudMode = process.env.CLOUD_MODE; export async function setAuthKey(user, expire = 0) { const authKey = `auth:${getRandomChars(32)}`; @@ -38,15 +31,6 @@ export function getAuthToken(req) { } } -export function parseAuthToken(req) { - try { - return parseSecureToken(getAuthToken(req), secret()); - } catch (e) { - log(e); - return null; - } -} - export function parseShareToken(req) { try { return parseToken(req.headers[SHARE_TOKEN_HEADER], secret()); @@ -56,21 +40,6 @@ export function parseShareToken(req) { } } -export function isValidToken(token, validation) { - try { - if (typeof validation === 'object') { - return !Object.keys(validation).find(key => token[key] !== validation[key]); - } else if (typeof validation === 'function') { - return validation(token); - } - } catch (e) { - log(e); - return false; - } - - return false; -} - export async function canViewWebsite({ user, shareToken }: Auth, websiteId: string) { if (user?.isAdmin) { return true; @@ -80,22 +49,24 @@ export async function canViewWebsite({ user, shareToken }: Auth, websiteId: stri return true; } - const teamWebsite = await getTeamWebsiteByTeamMemberId(websiteId, user.id); + const website = await loadWebsite(websiteId); - if (teamWebsite) { + if (user.id === website?.userId) { return true; } - const website = await loadWebsite(websiteId); - - if (website.userId) { - return user.id === website.userId; - } - - return false; + return !!(await findTeamWebsiteByUserId(websiteId, user.id)); } -export async function canCreateWebsite({ user }: Auth) { +export async function canCreateWebsite({ user, grant }: Auth) { + if (cloudMode) { + if (grant?.find(a => a === PERMISSIONS.websiteCreate)) { + return true; + } + + return false; + } + if (user.isAdmin) { return true; } @@ -108,17 +79,9 @@ export async function canUpdateWebsite({ user }: Auth, websiteId: string) { return true; } - if (!validate(websiteId)) { - return false; - } - const website = await loadWebsite(websiteId); - if (website.userId) { - return user.id === website.userId; - } - - return false; + return user.id === website?.userId; } export async function canDeleteWebsite({ user }: Auth, websiteId: string) { @@ -128,15 +91,42 @@ export async function canDeleteWebsite({ user }: Auth, websiteId: string) { const website = await loadWebsite(websiteId); - if (website.userId) { - return user.id === website.userId; - } - - return false; + return user.id === website?.userId; } -// To-do: Implement when payments are setup. -export async function canCreateTeam({ user }: Auth) { +export async function canViewReport(auth: Auth, report: Report) { + if (auth.user.isAdmin) { + return true; + } + + if (auth.user.id == report.userId) { + return true; + } + + return !!(await canViewWebsite(auth, report.websiteId)); +} + +export async function canUpdateReport({ user }: Auth, report: Report) { + if (user.isAdmin) { + return true; + } + + return user.id == report.userId; +} + +export async function canDeleteReport(auth: Auth, report: Report) { + return canUpdateReport(auth, report); +} + +export async function canCreateTeam({ user, grant }: Auth) { + if (cloudMode) { + if (grant?.find(a => a === PERMISSIONS.teamCreate)) { + return true; + } + + return false; + } + if (user.isAdmin) { return true; } @@ -144,7 +134,6 @@ export async function canCreateTeam({ user }: Auth) { return !!user; } -// To-do: Implement when payments are setup. export async function canViewTeam({ user }: Auth, teamId: string) { if (user.isAdmin) { return true; @@ -158,13 +147,9 @@ export async function canUpdateTeam({ user }: Auth, teamId: string) { return true; } - if (validate(teamId)) { - const teamUser = await getTeamUser(teamId, user.id); + const teamUser = await getTeamUser(teamId, user.id); - return hasPermission(teamUser.role, PERMISSIONS.teamUpdate); - } - - return false; + return teamUser && hasPermission(teamUser.role, PERMISSIONS.teamUpdate); } export async function canDeleteTeam({ user }: Auth, teamId: string) { @@ -172,13 +157,9 @@ export async function canDeleteTeam({ user }: Auth, teamId: string) { return true; } - if (validate(teamId)) { - const teamUser = await getTeamUser(teamId, user.id); + const teamUser = await getTeamUser(teamId, user.id); - return hasPermission(teamUser.role, PERMISSIONS.teamDelete); - } - - return false; + return teamUser && hasPermission(teamUser.role, PERMISSIONS.teamDelete); } export async function canDeleteTeamUser({ user }: Auth, teamId: string, removeUserId: string) { @@ -186,17 +167,13 @@ export async function canDeleteTeamUser({ user }: Auth, teamId: string, removeUs return true; } - if (validate(teamId) && validate(removeUserId)) { - if (removeUserId === user.id) { - return true; - } - - const teamUser = await getTeamUser(teamId, user.id); - - return hasPermission(teamUser.role, PERMISSIONS.teamUpdate); + if (removeUserId === user.id) { + return true; } - return false; + const teamUser = await getTeamUser(teamId, user.id); + + return teamUser && hasPermission(teamUser.role, PERMISSIONS.teamUpdate); } export async function canDeleteTeamWebsite({ user }: Auth, teamId: string, websiteId: string) { @@ -204,13 +181,13 @@ export async function canDeleteTeamWebsite({ user }: Auth, teamId: string, websi return true; } - if (validate(teamId) && validate(websiteId)) { - const teamWebsite = await getTeamWebsite(teamId, websiteId); + const teamWebsite = await getTeamWebsite(teamId, websiteId); - if (teamWebsite.website.userId === user.id) { - return true; - } + if (teamWebsite?.website?.userId === user.id) { + return true; + } + if (teamWebsite) { const teamUser = await getTeamUser(teamWebsite.teamId, user.id); return hasPermission(teamUser.role, PERMISSIONS.teamUpdate); diff --git a/lib/cache.ts b/src/lib/cache.ts similarity index 51% rename from lib/cache.ts rename to src/lib/cache.ts index 2aad7ed8..c54eda2e 100644 --- a/lib/cache.ts +++ b/src/lib/cache.ts @@ -1,46 +1,21 @@ import { User, Website } from '@prisma/client'; import redis from '@umami/redis-client'; -import { getSession, getUser, getWebsite } from '../queries'; +import { getSession, getUserById, getWebsiteById } from '../queries'; -const DELETED = 'DELETED'; - -async function fetchObject(key, query) { - const obj = await redis.get(key); - - if (obj === DELETED) { - return null; - } - - if (!obj) { - return query().then(async data => { - if (data) { - await redis.set(key, data); - } - - return data; - }); - } - - return obj; -} - -async function storeObject(key, data) { - return redis.set(key, data); -} - -async function deleteObject(key, soft = false) { - return soft ? redis.set(key, DELETED) : redis.del(key); -} +const { fetchObject, storeObject, deleteObject, expire } = redis; async function fetchWebsite(id): Promise { - return fetchObject(`website:${id}`, () => getWebsite({ id })); + return fetchObject(`website:${id}`, () => getWebsiteById(id), 86400); } async function storeWebsite(data) { const { id } = data; const key = `website:${id}`; - return storeObject(key, data); + const obj = await storeObject(key, data); + await expire(key, 86400); + + return obj; } async function deleteWebsite(id) { @@ -48,14 +23,17 @@ async function deleteWebsite(id) { } async function fetchUser(id): Promise { - return fetchObject(`user:${id}`, () => getUser({ id }, { includePassword: true })); + return fetchObject(`user:${id}`, () => getUserById(id, { includePassword: true }), 86400); } async function storeUser(data) { const { id } = data; const key = `user:${id}`; - return storeObject(key, data); + const obj = await storeObject(key, data); + await expire(key, 86400); + + return obj; } async function deleteUser(id) { @@ -63,20 +41,33 @@ async function deleteUser(id) { } async function fetchSession(id) { - return fetchObject(`session:${id}`, () => getSession({ id })); + return fetchObject(`session:${id}`, () => getSession(id), 86400); } async function storeSession(data) { const { id } = data; const key = `session:${id}`; - return storeObject(key, data); + const obj = await storeObject(key, data); + await expire(key, 86400); + + return obj; } async function deleteSession(id) { return deleteObject(`session:${id}`); } +async function fetchUserBlock(userId: string) { + const key = `user:block:${userId}`; + return redis.get(key); +} + +async function incrementUserBlock(userId: string) { + const key = `user:block:${userId}`; + return redis.incr(key); +} + export default { fetchWebsite, storeWebsite, @@ -87,5 +78,7 @@ export default { fetchSession, storeSession, deleteSession, + fetchUserBlock, + incrementUserBlock, enabled: redis.enabled, }; diff --git a/src/lib/charts.js b/src/lib/charts.js new file mode 100644 index 00000000..ff746cb5 --- /dev/null +++ b/src/lib/charts.js @@ -0,0 +1,62 @@ +import { StatusLight } from 'react-basics'; +import { formatDate } from 'lib/date'; +import { formatLongNumber } from 'lib/format'; + +export function renderNumberLabels(label) { + return +label > 1000 ? formatLongNumber(label) : label; +} + +export function renderDateLabels(unit, locale) { + return (label, index, values) => { + const d = new Date(values[index].value); + + switch (unit) { + case 'minute': + return formatDate(d, 'h:mm', locale); + case 'hour': + return formatDate(d, 'p', locale); + case 'day': + return formatDate(d, 'MMM d', locale); + case 'month': + return formatDate(d, 'MMM', locale); + case 'year': + return formatDate(d, 'YYY', locale); + default: + return label; + } + }; +} + +export function renderStatusTooltipPopup(unit, locale) { + return (setTooltipPopup, model) => { + const { opacity, labelColors, dataPoints } = model.tooltip; + + if (!dataPoints?.length || !opacity) { + setTooltipPopup(null); + return; + } + + const formats = { + millisecond: 'T', + second: 'pp', + minute: 'p', + hour: 'h:mm aaa - PP', + day: 'PPPP', + week: 'PPPP', + month: 'LLLL yyyy', + quarter: 'qqq', + year: 'yyyy', + }; + + setTooltipPopup( + <> +
{formatDate(new Date(dataPoints[0].raw.x), formats[unit], locale)}
+
+ + {formatLongNumber(dataPoints[0].raw.y)} {dataPoints[0].dataset.label} + +
+ , + ); + }; +} diff --git a/lib/clickhouse.ts b/src/lib/clickhouse.ts similarity index 53% rename from lib/clickhouse.ts rename to src/lib/clickhouse.ts index 90cf6088..bc10a6d4 100644 --- a/lib/clickhouse.ts +++ b/src/lib/clickhouse.ts @@ -2,9 +2,10 @@ import { ClickHouse } from 'clickhouse'; import dateFormat from 'dateformat'; import debug from 'debug'; import { CLICKHOUSE } from 'lib/db'; -import { getEventDataType } from './eventData'; -import { WebsiteMetricFilter } from './types'; -import { FILTER_COLUMNS } from './constants'; +import { QueryFilters, QueryOptions } from './types'; +import { FILTER_COLUMNS, OPERATORS } from './constants'; +import { loadWebsite } from './load'; +import { maxDate } from './date'; export const CLICKHOUSE_DATE_FORMATS = { minute: '%Y-%m-%d %H:%M:00', @@ -62,57 +63,29 @@ function getDateFormat(date) { return `'${dateFormat(date, 'UTC:yyyy-mm-dd HH:MM:ss')}'`; } -function getBetweenDates(field, startAt, endAt) { - return `${field} between ${getDateFormat(startAt)} and ${getDateFormat(endAt)}`; +function mapFilter(column, operator, name, type = 'String') { + switch (operator) { + case OPERATORS.equals: + return `${column} = {${name}:${type}}`; + case OPERATORS.notEquals: + return `${column} != {${name}:${type}}`; + default: + return ''; + } } -function getEventDataFilterQuery( - filters: { - eventKey?: string; - eventValue?: string | number | boolean | Date; - }[] = [], - params: any, -) { - const query = filters.reduce((ac, cv, i) => { - const type = getEventDataType(cv.eventValue); +function getFilterQuery(filters: QueryFilters = {}, options: QueryOptions = {}) { + const query = Object.keys(filters).reduce((arr, name) => { + const value = filters[name]; + const operator = value?.filter ?? OPERATORS.equals; + const column = FILTER_COLUMNS[name] ?? options?.columns?.[name]; - let value = cv.eventValue; + if (value !== undefined && column) { + arr.push(`and ${mapFilter(column, operator, name)}`); - ac.push(`and (event_key = {eventKey${i}:String}`); - - switch (type) { - case 'number': - ac.push(`and event_numeric_value = {eventValue${i}:UInt64})`); - break; - case 'string': - ac.push(`and event_string_value = {eventValue${i}:String})`); - break; - case 'boolean': - ac.push(`and event_string_value = {eventValue${i}:String})`); - value = cv ? 'true' : 'false'; - break; - case 'date': - ac.push(`and event_date_value = {eventValue${i}:DateTime('UTC')})`); - break; - } - - params[`eventKey${i}`] = cv.eventKey; - params[`eventValue${i}`] = value; - - return ac; - }, []); - - return query.join('\n'); -} - -function getFilterQuery(filters = {}, params = {}) { - const query = Object.keys(filters).reduce((arr, key) => { - const filter = filters[key]; - - if (filter !== undefined) { - const column = FILTER_COLUMNS[key] || key; - arr.push(`and ${column} = {${key}:String}`); - params[key] = decodeURIComponent(filter); + if (name === 'referrer') { + arr.push('and referrer_domain != {websiteDomain:String}'); + } } return arr; @@ -121,13 +94,31 @@ function getFilterQuery(filters = {}, params = {}) { return query.join('\n'); } -function parseFilters(filters: WebsiteMetricFilter = {}, params: any = {}) { +function normalizeFilters(filters = {}) { + return Object.keys(filters).reduce((obj, key) => { + const value = filters[key]; + + obj[key] = value?.value ?? value; + + return obj; + }, {}); +} + +async function parseFilters(websiteId: string, filters: QueryFilters = {}, options?: QueryOptions) { + const website = await loadWebsite(websiteId); + return { - filterQuery: getFilterQuery(filters, params), + filterQuery: getFilterQuery(filters, options), + params: { + ...normalizeFilters(filters), + websiteId, + startDate: maxDate(filters.startDate, website.resetAt), + websiteDomain: website.domain, + }, }; } -async function rawQuery(query, params = {}) { +async function rawQuery(query: string, params: object = {}): Promise { if (process.env.LOG_QUERY) { log('QUERY:\n', query); log('PARAMETERS:\n', params); @@ -135,7 +126,7 @@ async function rawQuery(query, params = {}) { await connect(); - return clickhouse.query(query, { params }).toPromise(); + return clickhouse.query(query, { params }).toPromise() as Promise; } async function findUnique(data) { @@ -143,7 +134,7 @@ async function findUnique(data) { throw `${data.length} records found when expecting 1.`; } - return data[0] ?? null; + return findFirst(data); } async function findFirst(data) { @@ -166,9 +157,7 @@ export default { getDateStringQuery, getDateQuery, getDateFormat, - getBetweenDates, getFilterQuery, - getEventDataFilterQuery, parseFilters, findUnique, findFirst, diff --git a/lib/client.ts b/src/lib/client.ts similarity index 100% rename from lib/client.ts rename to src/lib/client.ts diff --git a/lib/constants.ts b/src/lib/constants.ts similarity index 80% rename from lib/constants.ts rename to src/lib/constants.ts index 2ad87cbd..097771f9 100644 --- a/lib/constants.ts +++ b/src/lib/constants.ts @@ -18,6 +18,7 @@ export const DEFAULT_THEME = 'dark'; export const DEFAULT_ANIMATION_DURATION = 300; export const DEFAULT_DATE_RANGE = '24hour'; export const DEFAULT_WEBSITE_LIMIT = 10; +export const DEFAULT_RESET_DATE = '2000-01-01'; export const REALTIME_RANGE = 30; export const REALTIME_INTERVAL = 5000; @@ -29,6 +30,22 @@ export const FILTER_RANGE = 'filter-range'; export const FILTER_REFERRERS = 'filter-referrers'; export const FILTER_PAGES = 'filter-pages'; +export const USER_FILTER_TYPES = { + all: 'All', + username: 'Username', +} as const; +export const WEBSITE_FILTER_TYPES = { all: 'All', name: 'Name', domain: 'Domain' } as const; +export const TEAM_FILTER_TYPES = { all: 'All', name: 'Name', 'user:username': 'Owner' } as const; +export const REPORT_FILTER_TYPES = { + all: 'All', + name: 'Name', + description: 'Description', + type: 'Type', + 'user:username': 'Username', + 'website:name': 'Website Name', + 'website:domain': 'Website Domain', +} as const; + export const EVENT_COLUMNS = ['url', 'referrer', 'title', 'query', 'event']; export const SESSION_COLUMNS = [ @@ -47,8 +64,19 @@ export const FILTER_COLUMNS = { referrer: 'referrer_domain', title: 'page_title', query: 'url_query', - event: 'event_name', + os: 'os', + browser: 'browser', + device: 'device', + country: 'country', region: 'subdivision1', + city: 'city', + language: 'language', + event: 'event_name', +}; + +export const COLLECTION_TYPE = { + event: 'event', + identify: 'identify', }; export const EVENT_TYPE = { @@ -56,7 +84,7 @@ export const EVENT_TYPE = { customEvent: 2, } as const; -export const EVENT_DATA_TYPE = { +export const DATA_TYPE = { string: 1, number: 2, boolean: 3, @@ -64,6 +92,43 @@ export const EVENT_DATA_TYPE = { array: 5, } as const; +export const OPERATORS = { + equals: 'eq', + notEquals: 'neq', + set: 's', + notSet: 'ns', + contains: 'c', + doesNotContain: 'dnc', + true: 't', + false: 'f', + greaterThan: 'gt', + lessThan: 'lt', + greaterThanEquals: 'gte', + lessThanEquals: 'lte', + before: 'bf', + after: 'af', +} as const; + +export const DATA_TYPES = { + [DATA_TYPE.string]: 'string', + [DATA_TYPE.number]: 'number', + [DATA_TYPE.boolean]: 'boolean', + [DATA_TYPE.date]: 'date', + [DATA_TYPE.array]: 'array', +}; + +export const REPORT_TYPES = { + funnel: 'funnel', + insights: 'insights', + retention: 'retention', +} as const; + +export const REPORT_PARAMETERS = { + fields: 'fields', + filters: 'filters', + groups: 'groups', +} as const; + export const KAFKA_TOPIC = { event: 'event', eventData: 'event_data', @@ -72,6 +137,7 @@ export const KAFKA_TOPIC = { export const ROLES = { admin: 'admin', user: 'user', + viewOnly: 'view-only', teamOwner: 'team-owner', teamMember: 'team-member', } as const; @@ -94,6 +160,7 @@ export const ROLE_PERMISSIONS = { PERMISSIONS.websiteDelete, PERMISSIONS.teamCreate, ], + [ROLES.viewOnly]: [], [ROLES.teamOwner]: [PERMISSIONS.teamUpdate, PERMISSIONS.teamDelete], [ROLES.teamMember]: [], } as const; @@ -145,7 +212,12 @@ export const EVENT_COLORS = [ ]; export const DOMAIN_REGEX = - /^(localhost(:[1-9]\d{0,4})?|((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63})$/; + /^(localhost(:[1-9]\d{0,4})?|((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9-]+(-[a-z0-9-]+)*\.)+(xn--)?[a-z0-9-]{2,63})$/; +export const SHARE_ID_REGEX = /^[a-zA-Z0-9]{16}$/; +export const UUID_REGEX = + /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/; +export const HOSTNAME_REGEX = + /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/; export const DESKTOP_SCREEN_WIDTH = 1920; export const LAPTOP_SCREEN_WIDTH = 1024; @@ -158,7 +230,7 @@ export const DESKTOP_OS = [ 'BeOS', 'Chrome OS', 'Linux', - 'macOS', + 'Mac OS', 'Open BSD', 'OS/2', 'QNX', @@ -180,33 +252,34 @@ export const DESKTOP_OS = [ export const MOBILE_OS = ['Amazon OS', 'Android OS', 'BlackBerry OS', 'iOS', 'Windows Mobile']; export const BROWSERS = { + android: 'Android', aol: 'AOL', - edge: 'Edge', - 'edge-ios': 'Edge (iOS)', - yandexbrowser: 'Yandex', - kakaotalk: 'KaKaoTalk', - samsung: 'Samsung', - silk: 'Silk', - miui: 'MIUI', beaker: 'Beaker', - 'edge-chromium': 'Edge (Chromium)', + bb10: 'BlackBerry 10', chrome: 'Chrome', 'chromium-webview': 'Chrome (webview)', - phantomjs: 'PhantomJS', crios: 'Chrome (iOS)', + curl: 'Curl', + edge: 'Edge', + 'edge-chromium': 'Edge (Chromium)', + 'edge-ios': 'Edge (iOS)', + facebook: 'Facebook', firefox: 'Firefox', fxios: 'Firefox (iOS)', - 'opera-mini': 'Opera Mini', - opera: 'Opera', ie: 'IE', - bb10: 'BlackBerry 10', - android: 'Android', - ios: 'iOS', - safari: 'Safari', - facebook: 'Facebook', instagram: 'Instagram', + ios: 'iOS', 'ios-webview': 'iOS (webview)', + kakaotalk: 'KaKaoTalk', + miui: 'MIUI', + opera: 'Opera', + 'opera-mini': 'Opera Mini', + phantomjs: 'PhantomJS', + safari: 'Safari', + samsung: 'Samsung', + silk: 'Silk', searchbot: 'Searchbot', + yandexbrowser: 'Yandex', }; export const MAP_FILE = '/datamaps.world.json'; diff --git a/lib/crypto.js b/src/lib/crypto.js similarity index 65% rename from lib/crypto.js rename to src/lib/crypto.js index fcd3e2c0..fefaf13f 100644 --- a/lib/crypto.js +++ b/src/lib/crypto.js @@ -1,7 +1,6 @@ -import crypto from 'crypto'; -import { v4, v5 } from 'uuid'; import { startOfMonth } from 'date-fns'; import { hash } from 'next-basics'; +import { v4, v5, validate } from 'uuid'; export function secret() { return hash(process.env.APP_SECRET || process.env.DATABASE_URL); @@ -16,9 +15,9 @@ export function salt() { export function uuid(...args) { if (!args.length) return v4(); - return v5(hash(...args, salt()), v5.DNS); + return v5(hash(...args), v5.DNS); } -export function md5(...args) { - return crypto.createHash('md5').update(args.join('')).digest('hex'); +export function isUuid(value) { + return validate(value); } diff --git a/lib/eventData.ts b/src/lib/data.ts similarity index 63% rename from lib/eventData.ts rename to src/lib/data.ts index 4588d081..47023bb4 100644 --- a/lib/eventData.ts +++ b/src/lib/data.ts @@ -1,12 +1,12 @@ import { isValid, parseISO } from 'date-fns'; -import { EVENT_DATA_TYPE } from './constants'; -import { EventDataTypes } from './types'; +import { DATA_TYPE } from './constants'; +import { DynamicDataType } from './types'; export function flattenJSON( eventData: { [key: string]: any }, - keyValues: { key: string; value: any; eventDataType: EventDataTypes }[] = [], + keyValues: { key: string; value: any; dynamicDataType: DynamicDataType }[] = [], parentKey = '', -): { key: string; value: any; eventDataType: EventDataTypes }[] { +): { key: string; value: any; dynamicDataType: DynamicDataType }[] { return Object.keys(eventData).reduce( (acc, key) => { const value = eventData[key]; @@ -25,7 +25,7 @@ export function flattenJSON( ).keyValues; } -export function getEventDataType(value: any): string { +export function getDataType(value: any): string { let type: string = typeof value; if ((type === 'string' && isValid(value)) || isValid(parseISO(value))) { @@ -36,33 +36,34 @@ export function getEventDataType(value: any): string { } function createKey(key, value, acc: { keyValues: any[]; parentKey: string }) { - const type = getEventDataType(value); + const type = getDataType(value); - let eventDataType = null; + let dynamicDataType = null; switch (type) { case 'number': - eventDataType = EVENT_DATA_TYPE.number; + dynamicDataType = DATA_TYPE.number; break; case 'string': - eventDataType = EVENT_DATA_TYPE.string; + dynamicDataType = DATA_TYPE.string; break; case 'boolean': - eventDataType = EVENT_DATA_TYPE.boolean; + dynamicDataType = DATA_TYPE.boolean; + value = value ? 'true' : 'false'; break; case 'date': - eventDataType = EVENT_DATA_TYPE.date; + dynamicDataType = DATA_TYPE.date; break; case 'object': - eventDataType = EVENT_DATA_TYPE.array; + dynamicDataType = DATA_TYPE.array; value = JSON.stringify(value); break; default: - eventDataType = EVENT_DATA_TYPE.string; + dynamicDataType = DATA_TYPE.string; break; } - acc.keyValues.push({ key, value, eventDataType }); + acc.keyValues.push({ key, value, dynamicDataType }); } function getKeyName(key, parentKey) { diff --git a/lib/date.js b/src/lib/date.ts similarity index 59% rename from lib/date.js rename to src/lib/date.ts index 1cfca75d..14f0e13c 100644 --- a/lib/date.js +++ b/src/lib/date.ts @@ -26,10 +26,30 @@ import { differenceInCalendarMonths, differenceInCalendarYears, format, - parseISO, + max, + min, + isDate, + subWeeks, } from 'date-fns'; import { getDateLocale } from 'lib/lang'; +export const TIME_UNIT = { + minute: 'minute', + hour: 'hour', + day: 'day', + week: 'week', + month: 'month', + year: 'year', +}; + +const dateFuncs = { + minute: [differenceInMinutes, addMinutes, startOfMinute], + hour: [differenceInHours, addHours, startOfHour], + day: [differenceInCalendarDays, addDays, startOfDay], + month: [differenceInCalendarMonths, addMonths, startOfMonth], + year: [differenceInCalendarYears, addYears, startOfYear], +}; + export function getTimezone() { return moment.tz.guess(); } @@ -40,22 +60,38 @@ export function getLocalTime(t) { export function parseDateRange(value, locale = 'en-US') { if (typeof value === 'object') { - const { startDate, endDate } = value; + return value; + } + + if (value === 'all') { return { - ...value, - startDate: typeof startDate === 'string' ? parseISO(startDate) : startDate, - endDate: typeof endDate === 'string' ? parseISO(endDate) : endDate, + startDate: new Date(0), + endDate: new Date(1), + value, + }; + } + + if (value?.startsWith?.('range')) { + const [, startTime, endTime] = value.split(':'); + + const startDate = new Date(+startTime); + const endDate = new Date(+endTime); + + return { + ...getDateRangeValues(startDate, endDate), + value, }; } const now = new Date(); const dateLocale = getDateLocale(locale); - const match = value.match(/^(?[0-9-]+)(?hour|day|week|month|year)$/); + const match = value?.match?.(/^(?[0-9-]+)(?hour|day|week|month|year)$/); - if (!match) return {}; + if (!match) return null; const { num, unit } = match.groups; + const selectedUnit = { num, unit }; if (+num === 1) { switch (unit) { @@ -65,6 +101,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: endOfDay(now), unit: 'hour', value, + selectedUnit, }; case 'week': return { @@ -72,6 +109,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: endOfWeek(now, { locale: dateLocale }), unit: 'day', value, + selectedUnit, }; case 'month': return { @@ -79,6 +117,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: endOfMonth(now), unit: 'day', value, + selectedUnit, }; case 'year': return { @@ -86,6 +125,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: endOfYear(now), unit: 'month', value, + selectedUnit, }; } } @@ -98,6 +138,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: subDays(endOfDay(now), 1), unit: 'hour', value, + selectedUnit, }; case 'week': return { @@ -105,6 +146,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: subDays(endOfWeek(now, { locale: dateLocale }), 1), unit: 'day', value, + selectedUnit, }; case 'month': return { @@ -112,6 +154,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: subMonths(endOfMonth(now), 1), unit: 'day', value, + selectedUnit, }; case 'year': return { @@ -119,6 +162,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: subYears(endOfYear(now), 1), unit: 'month', value, + selectedUnit, }; } } @@ -130,6 +174,7 @@ export function parseDateRange(value, locale = 'en-US') { endDate: endOfDay(now), unit, value, + selectedUnit, }; case 'hour': return { @@ -137,21 +182,85 @@ export function parseDateRange(value, locale = 'en-US') { endDate: endOfHour(now), unit, value, + selectedUnit, }; } } -export function getDateRangeValues(startDate, endDate) { - let unit = 'year'; - if (differenceInHours(endDate, startDate) <= 48) { - unit = 'hour'; +export function incrementDateRange(value, increment) { + const { startDate, endDate, selectedUnit } = value; + + const { num, unit } = selectedUnit; + + const sub = num * increment; + + switch (unit) { + case 'hour': + return { + ...value, + startDate: subHours(startDate, sub), + endDate: subHours(endDate, sub), + value: 'range', + }; + case 'day': + return { + ...value, + startDate: subDays(startDate, sub), + endDate: subDays(endDate, sub), + value: 'range', + }; + case 'week': + return { + ...value, + startDate: subWeeks(startDate, sub), + endDate: subWeeks(endDate, sub), + value: 'range', + }; + case 'month': + return { + ...value, + startDate: subMonths(startDate, sub), + endDate: subMonths(endDate, sub), + value: 'range', + }; + case 'year': + return { + ...value, + startDate: subYears(startDate, sub), + endDate: subYears(endDate, sub), + value: 'range', + }; + } +} + +export function getAllowedUnits(startDate, endDate) { + const units = ['minute', 'hour', 'day', 'month', 'year']; + const minUnit = getMinimumUnit(startDate, endDate); + const index = units.indexOf(minUnit); + + return index >= 0 ? units.splice(index) : []; +} + +export function getMinimumUnit(startDate, endDate) { + if (differenceInMinutes(endDate, startDate) <= 60) { + return 'minute'; + } else if (differenceInHours(endDate, startDate) <= 48) { + return 'hour'; } else if (differenceInCalendarDays(endDate, startDate) <= 90) { - unit = 'day'; + return 'day'; } else if (differenceInCalendarMonths(endDate, startDate) <= 24) { - unit = 'month'; + return 'month'; } - return { startDate: startOfDay(startDate), endDate: endOfDay(endDate), unit }; + return 'year'; +} + +export function getDateRangeValues(startDate, endDate) { + return { + startDate: startOfDay(startDate), + endDate: endOfDay(endDate), + unit: getMinimumUnit(startDate, endDate), + }; } export function getDateFromString(str) { @@ -167,14 +276,6 @@ export function getDateFromString(str) { return new Date(year, month - 1, day); } -const dateFuncs = { - minute: [differenceInMinutes, addMinutes, startOfMinute], - hour: [differenceInHours, addHours, startOfHour], - day: [differenceInCalendarDays, addDays, startOfDay], - month: [differenceInCalendarMonths, addMonths, startOfMonth], - year: [differenceInCalendarYears, addYears, startOfYear], -}; - export function getDateArray(data, startDate, endDate, unit) { const arr = []; const [diff, add, normalize] = dateFuncs[unit]; @@ -203,7 +304,7 @@ export function getDateLength(startDate, endDate, unit) { return diff(endDate, startDate) + 1; } -export const customFormats = { +export const CUSTOM_FORMATS = { 'en-US': { p: 'ha', pp: 'h:mm:ss', @@ -215,8 +316,20 @@ export const customFormats = { }, }; -export function dateFormat(date, str, locale = 'en-US') { - return format(date, customFormats?.[locale]?.[str] || str, { - locale: getDateLocale(locale), - }); +export function formatDate(date, str, locale = 'en-US') { + return format( + typeof date === 'string' ? new Date(date) : date, + CUSTOM_FORMATS?.[locale]?.[str] || str, + { + locale: getDateLocale(locale), + }, + ); +} + +export function maxDate(...args) { + return max(args.filter(n => isDate(n))); +} + +export function minDate(...args) { + return min(args.filter(n => isDate(n))); } diff --git a/lib/db.js b/src/lib/db.js similarity index 91% rename from lib/db.js rename to src/lib/db.js index 19e46a3d..750cdec0 100644 --- a/lib/db.js +++ b/src/lib/db.js @@ -35,3 +35,7 @@ export async function runQuery(queries) { return queries[CLICKHOUSE](); } } + +export function notImplemented() { + throw new Error('Not implemented.'); +} diff --git a/lib/detect.ts b/src/lib/detect.ts similarity index 74% rename from lib/detect.ts rename to src/lib/detect.ts index 2597739b..86f812bd 100644 --- a/lib/detect.ts +++ b/src/lib/detect.ts @@ -1,8 +1,9 @@ import path from 'path'; -import requestIp from 'request-ip'; +import { getClientIp } from 'request-ip'; import { browserName, detectOS } from 'detect-browser'; import isLocalhost from 'is-localhost-ip'; import maxmind from 'maxmind'; +import { safeDecodeURIComponent } from 'next-basics'; import { DESKTOP_OS, @@ -25,7 +26,7 @@ export function getIpAddress(req) { return req.headers['cf-connecting-ip']; } - return requestIp.getClientIp(req); + return getClientIp(req); } export function getDevice(screen, os) { @@ -62,15 +63,29 @@ export async function getLocation(ip, req) { return; } - if (req.headers['x-vercel-ip-country']) { - const country = req.headers['x-vercel-ip-country']; - const region = req.headers['x-vercel-ip-country-region']; - const city = req.headers['x-vercel-ip-city']; + // Cloudflare headers + if (req.headers['cf-ipcountry']) { + const country = safeDecodeURIComponent(req.headers['cf-ipcountry']); + const subdivision1 = safeDecodeURIComponent(req.headers['cf-region-code']); + const city = safeDecodeURIComponent(req.headers['cf-ipcity']); return { country, - subdivision1: region, - city: city ? decodeURIComponent(city) : undefined, + subdivision1: subdivision1.includes('-') ? subdivision1 : `${country}-${subdivision1}`, + city, + }; + } + + // Vercel headers + if (req.headers['x-vercel-ip-country']) { + const country = safeDecodeURIComponent(req.headers['x-vercel-ip-country']); + const subdivision1 = safeDecodeURIComponent(req.headers['x-vercel-ip-country-region']); + const city = safeDecodeURIComponent(req.headers['x-vercel-ip-city']); + + return { + country, + subdivision1: subdivision1.includes('-') ? subdivision1 : `${country}-${subdivision1}`, + city, }; } diff --git a/lib/filters.js b/src/lib/filters.js similarity index 100% rename from lib/filters.js rename to src/lib/filters.js diff --git a/lib/format.js b/src/lib/format.js similarity index 100% rename from lib/format.js rename to src/lib/format.js diff --git a/lib/kafka.ts b/src/lib/kafka.ts similarity index 94% rename from lib/kafka.ts rename to src/lib/kafka.ts index 3d3e281c..10326888 100644 --- a/lib/kafka.ts +++ b/src/lib/kafka.ts @@ -61,8 +61,8 @@ async function getProducer(): Promise { return producer; } -function getDateFormat(date): string { - return dateFormat(date, 'UTC:yyyy-mm-dd HH:MM:ss'); +function getDateFormat(date: Date, format?: string): string { + return dateFormat(date, format ? format : 'UTC:yyyy-mm-dd HH:MM:ss'); } async function sendMessage( diff --git a/lib/lang.js b/src/lib/lang.js similarity index 97% rename from lib/lang.js rename to src/lib/lang.js index 0b03c449..caf18264 100644 --- a/lib/lang.js +++ b/src/lib/lang.js @@ -74,6 +74,7 @@ export const languages = { 'lt-LT': { label: 'Lietuvių', dateLocale: lt }, 'mn-MN': { label: 'Монгол', dateLocale: mn }, 'ms-MY': { label: 'Malay', dateLocale: ms }, + 'my-MM': { label: 'မြန်မာဘာသာ', dateLocale: enUS }, 'nl-NL': { label: 'Nederlands', dateLocale: nl }, 'nb-NO': { label: 'Norsk Bokmål', dateLocale: nb }, 'pl-PL': { label: 'Polski', dateLocale: pl }, diff --git a/lib/query.ts b/src/lib/load.ts similarity index 80% rename from lib/query.ts rename to src/lib/load.ts index 4ce18b09..d980f8e9 100644 --- a/lib/query.ts +++ b/src/lib/load.ts @@ -1,5 +1,5 @@ import cache from 'lib/cache'; -import { getWebsite, getSession, getUser } from 'queries'; +import { getSession, getUserById, getWebsiteById } from 'queries'; import { User, Website, Session } from '@prisma/client'; export async function loadWebsite(websiteId: string): Promise { @@ -8,7 +8,7 @@ export async function loadWebsite(websiteId: string): Promise { if (cache.enabled) { website = await cache.fetchWebsite(websiteId); } else { - website = await getWebsite({ id: websiteId }); + website = await getWebsiteById(websiteId); } if (!website || website.deletedAt) { @@ -24,7 +24,7 @@ export async function loadSession(sessionId: string): Promise { if (cache.enabled) { session = await cache.fetchSession(sessionId); } else { - session = await getSession({ id: sessionId }); + session = await getSession(sessionId); } if (!session) { @@ -40,7 +40,7 @@ export async function loadUser(userId: string): Promise { if (cache.enabled) { user = await cache.fetchUser(userId); } else { - user = await getUser({ id: userId }); + user = await getUserById(userId); } if (!user || user.deletedAt) { diff --git a/lib/middleware.ts b/src/lib/middleware.ts similarity index 61% rename from lib/middleware.ts rename to src/lib/middleware.ts index 79c48404..edf3e929 100644 --- a/lib/middleware.ts +++ b/src/lib/middleware.ts @@ -1,14 +1,20 @@ -import { createMiddleware, unauthorized, badRequest, parseSecureToken } from 'next-basics'; -import debug from 'debug'; -import cors from 'cors'; -import { validate } from 'uuid'; import redis from '@umami/redis-client'; -import { findSession } from 'lib/session'; +import cors from 'cors'; +import debug from 'debug'; import { getAuthToken, parseShareToken } from 'lib/auth'; -import { secret } from 'lib/crypto'; import { ROLES } from 'lib/constants'; -import { getUser } from '../queries'; +import { isUuid, secret } from 'lib/crypto'; +import { findSession } from 'lib/session'; +import { + badRequest, + createMiddleware, + parseSecureToken, + tooManyRequest, + unauthorized, +} from 'next-basics'; import { NextApiRequestCollect } from 'pages/api/send'; +import { getUserById } from '../queries'; +import { NextApiRequestQueryBody } from './types'; const log = debug('umami:middleware'); @@ -30,6 +36,9 @@ export const useSession = createMiddleware(async (req, res, next) => { (req as any).session = session; } catch (e: any) { + if (e.message === 'Usage Limit.') { + return tooManyRequest(res, e.message); + } return badRequest(res, e.message); } @@ -42,16 +51,16 @@ export const useAuth = createMiddleware(async (req, res, next) => { const shareToken = await parseShareToken(req); let user = null; - const { userId, authKey } = payload || {}; + const { userId, authKey, grant } = payload || {}; - if (validate(userId)) { - user = await getUser({ id: userId }); + if (isUuid(userId)) { + user = await getUserById(userId); } else if (redis.enabled && authKey) { user = await redis.get(authKey); } if (process.env.NODE_ENV === 'development') { - log({ token, shareToken, payload, user }); + log({ token, shareToken, payload, user, grant }); } if (!user?.id && !shareToken) { @@ -63,6 +72,25 @@ export const useAuth = createMiddleware(async (req, res, next) => { user.isAdmin = user.role === ROLES.admin; } - (req as any).auth = { user, token, shareToken, authKey }; + (req as any).auth = { + user, + grant, + token, + shareToken, + authKey, + }; + + next(); +}); + +export const useValidate = createMiddleware(async (req: any, res, next) => { + try { + const { yup } = req as NextApiRequestQueryBody; + + yup[req.method] && yup[req.method].validateSync({ ...req.query, ...req.body }); + } catch (e: any) { + return badRequest(res, e.message); + } + next(); }); diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts new file mode 100644 index 00000000..a9832c28 --- /dev/null +++ b/src/lib/prisma.ts @@ -0,0 +1,229 @@ +import prisma from '@umami/prisma-client'; +import moment from 'moment-timezone'; +import { MYSQL, POSTGRESQL, getDatabaseType } from 'lib/db'; +import { FILTER_COLUMNS, SESSION_COLUMNS, OPERATORS } from './constants'; +import { loadWebsite } from './load'; +import { maxDate } from './date'; +import { QueryFilters, QueryOptions, SearchFilter } from './types'; +import { Prisma } from '@prisma/client'; + +const MYSQL_DATE_FORMATS = { + minute: '%Y-%m-%d %H:%i:00', + hour: '%Y-%m-%d %H:00:00', + day: '%Y-%m-%d', + month: '%Y-%m-01', + year: '%Y-01-01', +}; + +const POSTGRESQL_DATE_FORMATS = { + minute: 'YYYY-MM-DD HH24:MI:00', + hour: 'YYYY-MM-DD HH24:00:00', + day: 'YYYY-MM-DD', + month: 'YYYY-MM-01', + year: 'YYYY-01-01', +}; + +function getAddMinutesQuery(field: string, minutes: number): string { + const db = getDatabaseType(process.env.DATABASE_URL); + + if (db === POSTGRESQL) { + return `${field} + interval '${minutes} minute'`; + } + + if (db === MYSQL) { + return `DATE_ADD(${field}, interval ${minutes} minute)`; + } +} + +function getDayDiffQuery(field1: string, field2: string): string { + const db = getDatabaseType(process.env.DATABASE_URL); + + if (db === POSTGRESQL) { + return `${field1}::date - ${field2}::date`; + } + + if (db === MYSQL) { + return `DATEDIFF(${field1}, ${field2})`; + } +} + +function getCastColumnQuery(field: string, type: string): string { + const db = getDatabaseType(process.env.DATABASE_URL); + + if (db === POSTGRESQL) { + return `${field}::${type}`; + } + + if (db === MYSQL) { + return `${field}`; + } +} + +function getDateQuery(field: string, unit: string, timezone?: string): string { + const db = getDatabaseType(); + + if (db === POSTGRESQL) { + if (timezone) { + return `to_char(date_trunc('${unit}', ${field} at time zone '${timezone}'), '${POSTGRESQL_DATE_FORMATS[unit]}')`; + } + return `to_char(date_trunc('${unit}', ${field}), '${POSTGRESQL_DATE_FORMATS[unit]}')`; + } + + if (db === MYSQL) { + if (timezone) { + const tz = moment.tz(timezone).format('Z'); + + return `date_format(convert_tz(${field},'+00:00','${tz}'), '${MYSQL_DATE_FORMATS[unit]}')`; + } + + return `date_format(${field}, '${MYSQL_DATE_FORMATS[unit]}')`; + } +} + +function getTimestampIntervalQuery(field: string): string { + const db = getDatabaseType(); + + if (db === POSTGRESQL) { + return `floor(extract(epoch from max(${field}) - min(${field})))`; + } + + if (db === MYSQL) { + return `floor(unix_timestamp(max(${field})) - unix_timestamp(min(${field})))`; + } +} + +function mapFilter(column, operator, name, type = 'varchar') { + switch (operator) { + case OPERATORS.equals: + return `${column} = {{${name}::${type}}}`; + case OPERATORS.notEquals: + return `${column} != {{${name}::${type}}}`; + default: + return ''; + } +} + +function getFilterQuery(filters: QueryFilters = {}, options: QueryOptions = {}): string { + const query = Object.keys(filters).reduce((arr, name) => { + const value = filters[name]; + const operator = value?.filter ?? OPERATORS.equals; + const column = FILTER_COLUMNS[name] ?? options?.columns?.[name]; + + if (value !== undefined && column) { + arr.push(`and ${mapFilter(column, operator, name)}`); + + if (name === 'referrer') { + arr.push( + 'and (website_event.referrer_domain != {{websiteDomain}} or website_event.referrer_domain is null)', + ); + } + } + + return arr; + }, []); + + return query.join('\n'); +} + +function normalizeFilters(filters = {}) { + return Object.keys(filters).reduce((obj, key) => { + const value = filters[key]; + + obj[key] = value?.value ?? value; + + return obj; + }, {}); +} + +async function parseFilters(websiteId, filters: QueryFilters = {}, options: QueryOptions = {}) { + const website = await loadWebsite(websiteId); + + return { + joinSession: + options?.joinSession || Object.keys(filters).find(key => SESSION_COLUMNS.includes(key)) + ? `inner join session on website_event.session_id = session.session_id` + : '', + filterQuery: getFilterQuery(filters, options), + params: { + ...normalizeFilters(filters), + websiteId, + startDate: maxDate(filters.startDate, website.resetAt), + websiteDomain: website.domain, + }, + }; +} + +async function rawQuery(sql: string, data: object): Promise { + const db = getDatabaseType(); + const params = []; + + if (db !== POSTGRESQL && db !== MYSQL) { + return Promise.reject(new Error('Unknown database.')); + } + + const query = sql?.replaceAll(/\{\{\s*(\w+)(::\w+)?\s*\}\}/g, (...args) => { + const [, name, type] = args; + params.push(data[name]); + + return db === MYSQL ? '?' : `$${params.length}${type ?? ''}`; + }); + + return prisma.rawQuery(query, params); +} + +function getPageFilters(filters: SearchFilter): [ + { + orderBy: { + [x: string]: string; + }[]; + take: number; + skip: number; + }, + { + pageSize: number; + page: number; + orderBy: string; + }, +] { + const { pageSize = 10, page = 1, orderBy } = filters || {}; + + return [ + { + ...(pageSize > 0 && { take: pageSize, skip: pageSize * (page - 1) }), + ...(orderBy && { + orderBy: [ + { + [orderBy]: 'asc', + }, + ], + }), + }, + { pageSize, page: +page, orderBy }, + ]; +} + +function getSearchMode(): { mode?: Prisma.QueryMode } { + const db = getDatabaseType(); + + if (db === POSTGRESQL) { + return { + mode: 'insensitive', + }; + } + + return {}; +} + +export default { + ...prisma, + getAddMinutesQuery, + getDayDiffQuery, + getCastColumnQuery, + getDateQuery, + getTimestampIntervalQuery, + getFilterQuery, + parseFilters, + getPageFilters, + getSearchMode, + rawQuery, +}; diff --git a/src/lib/query.ts b/src/lib/query.ts new file mode 100644 index 00000000..88ce62d4 --- /dev/null +++ b/src/lib/query.ts @@ -0,0 +1,31 @@ +import { NextApiRequest } from 'next'; +import { getAllowedUnits, getMinimumUnit } from './date'; +import { getWebsiteDateRange } from '../queries'; + +export async function parseDateRangeQuery(req: NextApiRequest) { + const { id: websiteId, startAt, endAt, unit } = req.query; + + // All-time + if (+startAt === 0 && +endAt === 1) { + const result = await getWebsiteDateRange(websiteId as string); + const { min, max } = result[0]; + const startDate = new Date(min); + const endDate = new Date(max); + + return { + startDate, + endDate, + unit: getMinimumUnit(startDate, endDate), + }; + } + + const startDate = new Date(+startAt); + const endDate = new Date(+endAt); + const minUnit = getMinimumUnit(startDate, endDate); + + return { + startDate, + endDate, + unit: (getAllowedUnits(startDate, endDate).includes(unit as string) ? unit : minUnit) as string, + }; +} diff --git a/lib/session.ts b/src/lib/session.ts similarity index 62% rename from lib/session.ts rename to src/lib/session.ts index 937bfef2..85c173c5 100644 --- a/lib/session.ts +++ b/src/lib/session.ts @@ -1,13 +1,27 @@ -import clickhouse from 'lib/clickhouse'; -import { secret, uuid } from 'lib/crypto'; +import { isUuid, secret, uuid } from 'lib/crypto'; import { getClientInfo, getJsonBody } from 'lib/detect'; import { parseToken } from 'next-basics'; import { CollectRequestBody, NextApiRequestCollect } from 'pages/api/send'; import { createSession } from 'queries'; -import { validate } from 'uuid'; -import { loadSession, loadWebsite } from './query'; +import cache from './cache'; +import clickhouse from './clickhouse'; +import { loadSession, loadWebsite } from './load'; -export async function findSession(req: NextApiRequestCollect) { +export async function findSession(req: NextApiRequestCollect): Promise<{ + id: any; + websiteId: string; + hostname: string; + browser: string; + os: any; + device: string; + screen: string; + language: string; + country: any; + subdivision1: any; + subdivision2: any; + city: any; + ownerId: string; +}> { const { payload } = getJsonBody(req); if (!payload) { @@ -21,6 +35,8 @@ export async function findSession(req: NextApiRequestCollect) { const result = await parseToken(cacheToken, secret()); if (result) { + await checkUserBlock(result?.ownerId); + return result; } } @@ -28,7 +44,13 @@ export async function findSession(req: NextApiRequestCollect) { // Verify payload const { website: websiteId, hostname, screen, language } = payload; - if (!validate(websiteId)) { + // Check the hostname value for legality to eliminate dirty data + const validHostnameRegex = /^[\w-.]+$/; + if (!validHostnameRegex.test(hostname)) { + throw new Error('Invalid hostname.'); + } + + if (!isUuid(websiteId)) { throw new Error('Invalid website ID.'); } @@ -39,8 +61,11 @@ export async function findSession(req: NextApiRequestCollect) { throw new Error(`Website not found: ${websiteId}.`); } + await checkUserBlock(website.userId); + const { userAgent, browser, os, ip, country, subdivision1, subdivision2, city, device } = await getClientInfo(req, payload); + const sessionId = uuid(websiteId, hostname, ip, userAgent); // Clickhouse does not require session lookup @@ -50,7 +75,7 @@ export async function findSession(req: NextApiRequestCollect) { websiteId, hostname, browser, - os, + os: os as any, device, screen, language, @@ -58,6 +83,7 @@ export async function findSession(req: NextApiRequestCollect) { subdivision1, subdivision2, city, + ownerId: website.userId, }; } @@ -88,5 +114,13 @@ export async function findSession(req: NextApiRequestCollect) { } } - return session; + return { ...session, ownerId: website.userId }; +} + +async function checkUserBlock(userId: string) { + if (process.env.ENABLE_BLOCKER && (await cache.fetchUserBlock(userId))) { + await cache.incrementUserBlock(userId); + + throw new Error('Usage Limit.'); + } } diff --git a/src/lib/sql.ts b/src/lib/sql.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 00000000..3685753e --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,217 @@ +import { NextApiRequest } from 'next'; +import { + COLLECTION_TYPE, + DATA_TYPE, + EVENT_TYPE, + KAFKA_TOPIC, + PERMISSIONS, + REPORT_FILTER_TYPES, + REPORT_TYPES, + ROLES, + TEAM_FILTER_TYPES, + USER_FILTER_TYPES, + WEBSITE_FILTER_TYPES, +} from './constants'; +import * as yup from 'yup'; +import { TIME_UNIT } from './date'; + +type ObjectValues = T[keyof T]; + +export type TimeUnit = ObjectValues; +export type Permission = ObjectValues; + +export type CollectionType = ObjectValues; +export type Role = ObjectValues; +export type EventType = ObjectValues; +export type DynamicDataType = ObjectValues; +export type KafkaTopic = ObjectValues; +export type ReportType = ObjectValues; + +export type ReportSearchFilterType = ObjectValues; +export type UserSearchFilterType = ObjectValues; +export type WebsiteSearchFilterType = ObjectValues; +export type TeamSearchFilterType = ObjectValues; + +export interface WebsiteSearchFilter extends SearchFilter { + userId?: string; + teamId?: string; + includeTeams?: boolean; + onlyTeams?: boolean; +} + +export interface UserSearchFilter extends SearchFilter { + teamId?: string; +} + +export interface TeamSearchFilter extends SearchFilter { + userId?: string; +} + +export interface ReportSearchFilter extends SearchFilter { + userId?: string; + websiteId?: string; + includeTeams?: boolean; +} + +export interface SearchFilter { + filter?: string; + filterType?: T; + pageSize: number; + page: number; + orderBy?: string; +} + +export interface FilterResult { + data: T; + count: number; + pageSize: number; + page: number; + orderBy?: string; +} + +export interface DynamicData { + [key: string]: number | string | DynamicData | number[] | string[] | DynamicData[]; +} + +export interface Auth { + user?: { + id: string; + username: string; + role: string; + isAdmin: boolean; + }; + grant?: Permission[]; + shareToken?: { + websiteId: string; + }; +} + +export interface YupRequest { + GET?: yup.ObjectSchema; + POST?: yup.ObjectSchema; + PUT?: yup.ObjectSchema; + DELETE?: yup.ObjectSchema; +} + +export interface NextApiRequestQueryBody extends NextApiRequest { + auth?: Auth; + query: TQuery & { [key: string]: string | string[] }; + body: TBody; + headers: any; + yup: YupRequest; +} + +export interface NextApiRequestAuth extends NextApiRequest { + auth?: Auth; + headers: any; +} + +export interface User { + id: string; + username: string; + password?: string; + role: string; + createdAt?: Date; +} + +export interface Website { + id: string; + userId: string; + resetAt: Date; + name: string; + domain: string; + shareId: string; + createdAt: Date; +} + +export interface Share { + id: string; + token: string; +} + +export interface WebsiteActive { + x: number; +} + +export interface WebsiteMetric { + x: string; + y: number; +} + +export interface WebsiteEventMetric { + x: string; + t: string; + y: number; +} + +export interface WebsiteEventData { + eventName?: string; + fieldName: string; + dataType: number; + fieldValue?: string; + total: number; +} + +export interface WebsitePageviews { + pageviews: { + t: string; + y: number; + }; + sessions: { + t: string; + y: number; + }; +} + +export interface WebsiteStats { + pageviews: { value: number; change: number }; + uniques: { value: number; change: number }; + bounces: { value: number; change: number }; + totalTime: { value: number; change: number }; +} + +export interface RealtimeInit { + websites: Website[]; + token: string; + data: RealtimeUpdate; +} + +export interface RealtimeUpdate { + pageviews: any[]; + sessions: any[]; + events: any[]; + timestamp: number; +} + +export interface DateRange { + startDate: Date; + endDate: Date; + value: string; + unit?: TimeUnit; + selectedUnit?: TimeUnit; +} + +export interface QueryFilters { + startDate?: Date; + endDate?: Date; + timezone?: string; + unit?: string; + eventType?: number; + url?: string; + referrer?: string; + title?: string; + query?: string; + os?: string; + browser?: string; + device?: string; + country?: string; + region?: string; + city?: string; + language?: string; + event?: string; +} + +export interface QueryOptions { + joinSession?: boolean; + columns?: { [key: string]: string }; +} diff --git a/src/lib/yup.ts b/src/lib/yup.ts new file mode 100644 index 00000000..a9d21028 --- /dev/null +++ b/src/lib/yup.ts @@ -0,0 +1,19 @@ +import * as yup from 'yup'; + +export function getDateRangeValidation() { + return { + startAt: yup.number().integer().required(), + endAt: yup.number().integer().moreThan(yup.ref('startAt')).required(), + }; +} + +// ex: /funnel|insights|retention/i +export function getFilterValidation(matchRegex) { + return { + filter: yup.string(), + filterType: yup.string().matches(matchRegex), + pageSize: yup.number().integer().positive().max(200), + page: yup.number().integer().positive(), + orderBy: yup.string(), + }; +} diff --git a/pages/404.js b/src/pages/404.js similarity index 90% rename from pages/404.js rename to src/pages/404.js index 4a5f4bd9..8fa13a9c 100644 --- a/pages/404.js +++ b/src/pages/404.js @@ -1,6 +1,6 @@ import { Row, Column, Flexbox } from 'react-basics'; import AppLayout from 'components/layout/AppLayout'; -import useMessages from 'hooks/useMessages'; +import useMessages from 'components/hooks/useMessages'; export default function Custom404() { const { formatMessage, labels } = useMessages(); diff --git a/src/pages/_app.js b/src/pages/_app.js new file mode 100644 index 00000000..0513250d --- /dev/null +++ b/src/pages/_app.js @@ -0,0 +1,54 @@ +import { IntlProvider } from 'react-intl'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ReactBasicsProvider } from 'react-basics'; +import Head from 'next/head'; +import Script from 'next/script'; +import { useRouter } from 'next/router'; +import ErrorBoundary from 'components/common/ErrorBoundary'; +import useLocale from 'components/hooks/useLocale'; +import '@fontsource/inter/400.css'; +import '@fontsource/inter/700.css'; +import 'react-basics/dist/styles.css'; +import 'styles/variables.css'; +import 'styles/locale.css'; +import 'styles/index.css'; +import 'chartjs-adapter-date-fns'; + +const client = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + refetchOnWindowFocus: false, + }, + }, +}); + +export default function App({ Component, pageProps }) { + const { locale, messages } = useLocale(); + const { basePath, pathname } = useRouter(); + + return ( + + null}> + + + + + + + + {/* */} + + + + + + + + {!pathname.includes('/share/') &&