Merge pull request #1387 from umami-software/dev

v1.37.0
This commit is contained in:
Mike Cao 2022-08-09 17:13:39 -05:00 committed by GitHub
commit 2f24a8775e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
163 changed files with 3619 additions and 2728 deletions

View File

@ -12,15 +12,11 @@ WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ARG DATABASE_URL
ARG DATABASE_TYPE
ARG BASE_PATH
ARG DISABLE_LOGIN
ENV DATABASE_URL $DATABASE_URL
ENV DATABASE_TYPE $DATABASE_TYPE
ENV BASE_PATH $BASE_PATH
ENV DISABLE_LOGIN $DISABLE_LOGIN
ENV NEXT_TELEMETRY_DISABLED 1
@ -36,12 +32,11 @@ ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN yarn global add prisma
RUN yarn add npm-run-all dotenv
RUN yarn add npm-run-all dotenv prisma
# You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/next.config.js .
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/scripts ./scripts

View File

@ -1 +0,0 @@
web: npm run start-env

View File

@ -30,7 +30,7 @@ export default function UpdateNotice() {
if (!checked) {
checkVersion();
}
}, []);
}, [checked]);
if (!hasUpdate || dismissed) {
return null;

View File

@ -4,10 +4,12 @@ import { useRouter } from 'next/router';
import Button from 'components/common/Button';
import FormLayout, { FormButtons, FormRow } from 'components/layout/FormLayout';
import CopyButton from 'components/common/CopyButton';
import useConfig from 'hooks/useConfig';
export default function TrackingCodeForm({ values, onClose }) {
const ref = useRef();
const { basePath } = useRouter();
const { trackerScriptName } = useConfig();
return (
<FormLayout>
@ -24,7 +26,9 @@ export default function TrackingCodeForm({ values, onClose }) {
rows={3}
cols={60}
spellCheck={false}
defaultValue={`<script async defer data-website-id="${values.website_uuid}" src="${document.location.origin}${basePath}/umami.js"></script>`}
defaultValue={`<script async defer data-website-id="${values.website_uuid}" src="${
document.location.origin
}${basePath}/${trackerScriptName ? `${trackerScriptName}.js` : 'umami.js'}"></script>`}
readOnly
/>
</FormRow>

View File

@ -1,13 +1,13 @@
import React from 'react';
import { useRouter } from 'next/router';
import Script from 'next/script';
import classNames from 'classnames';
import { FormattedMessage } from 'react-intl';
import Link from 'components/common/Link';
import styles from './Footer.module.css';
import useStore from 'store/version';
import { HOMEPAGE_URL, REPO_URL } from 'lib/constants';
import { CURRENT_VERSION, HOMEPAGE_URL, REPO_URL } from 'lib/constants';
export default function Footer() {
const { current } = useStore();
const { pathname } = useRouter();
return (
<footer className={classNames(styles.footer, 'row')}>
@ -26,11 +26,9 @@ export default function Footer() {
/>
</div>
<div className={classNames(styles.version, 'col-12 col-md-4')}>
<Link href={REPO_URL}>{`v${current}`}</Link>
<Link href={REPO_URL}>{`v${CURRENT_VERSION}`}</Link>
</div>
{!process.env.telemetryDisabled && (
<img src={`https://i.umami.is/a.png?v=${current}`} alt="" />
)}
{!pathname.includes('/share/') && <Script src={`/telemetry.js`} />}
</footer>
);
}

View File

@ -8,22 +8,26 @@ import ThemeButton from 'components/settings/ThemeButton';
import HamburgerButton from 'components/common/HamburgerButton';
import UpdateNotice from 'components/common/UpdateNotice';
import UserButton from 'components/settings/UserButton';
import { HOMEPAGE_URL } from 'lib/constants';
import useConfig from '/hooks/useConfig';
import useUser from 'hooks/useUser';
import Logo from 'assets/logo.svg';
import styles from './Header.module.css';
import useUser from 'hooks/useUser';
import { HOMEPAGE_URL } from 'lib/constants';
export default function Header() {
const { user } = useUser();
const { pathname } = useRouter();
const { updatesDisabled } = useConfig();
const isSharePage = pathname.includes('/share/');
const allowUpdate = user?.is_admin && !updatesDisabled && !isSharePage;
return (
<>
{user?.is_admin && !process.env.updatesDisabled && <UpdateNotice />}
{allowUpdate && <UpdateNotice />}
<header className={classNames(styles.header, 'row')}>
<div className={styles.title}>
<Icon icon={<Logo />} size="large" className={styles.logo} />
<Link href={pathname.includes('/share') ? HOMEPAGE_URL : '/'}>umami</Link>
<Link href={isSharePage ? HOMEPAGE_URL : '/'}>umami</Link>
</div>
<HamburgerButton />
{user && (

View File

@ -12,7 +12,7 @@ export default function EventsChart({ websiteId, className, token }) {
const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId);
const [timezone] = useTimezone();
const {
query: { url, eventType },
query: { url, eventName },
} = usePageQuery();
const { data, loading } = useFetch(
@ -24,11 +24,11 @@ export default function EventsChart({ websiteId, className, token }) {
unit,
tz: timezone,
url,
event_type: eventType,
event_name: eventName,
token,
},
},
[modified, eventType],
[modified, eventName],
);
const datasets = useMemo(() => {

View File

@ -1,62 +1,26 @@
import React, { useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { defineMessages, useIntl } from 'react-intl';
import MetricsTable from './MetricsTable';
import Tag from 'components/common/Tag';
import DropDown from 'components/common/DropDown';
import { eventTypeFilter } from 'lib/filters';
import usePageQuery from 'hooks/usePageQuery';
import styles from './EventsTable.module.css';
const EVENT_FILTER_DEFAULT = {
value: 'all',
label: <FormattedMessage id="label.all-events" defaultMessage="All events" />,
};
const messages = defineMessages({
events: { id: 'metrics.events', defaultMessage: 'Events' },
actions: { id: 'metrics.actions', defaultMessage: 'Actions' },
});
export default function EventsTable({ websiteId, ...props }) {
const [eventType, setEventType] = useState(EVENT_FILTER_DEFAULT.value);
const [eventTypes, setEventTypes] = useState([]);
const { resolve, router } = usePageQuery();
const dropDownOptions = [EVENT_FILTER_DEFAULT, ...eventTypes.map(t => ({ value: t, label: t }))];
const { formatMessage } = useIntl();
function handleDataLoad(data) {
setEventTypes([...new Set(data.map(({ x }) => x.split('\t')[0]))]);
props.onDataLoad?.(data);
}
function handleChange(value) {
router.replace(resolve({ eventType: value === 'all' ? undefined : value }));
setEventType(value);
}
return (
<>
{eventTypes?.length > 1 && (
<div className={styles.filter}>
<DropDown value={eventType} options={dropDownOptions} onChange={handleChange} />
</div>
)}
<MetricsTable
{...props}
title={<FormattedMessage id="metrics.events" defaultMessage="Events" />}
type="event"
metric={<FormattedMessage id="metrics.actions" defaultMessage="Actions" />}
websiteId={websiteId}
dataFilter={eventTypeFilter}
filterOptions={eventType === EVENT_FILTER_DEFAULT.value ? [] : [eventType]}
renderLabel={({ x }) => <Label value={x} />}
onDataLoad={handleDataLoad}
/>
</>
<MetricsTable
{...props}
title={formatMessage(messages.events)}
type="event"
metric={formatMessage(messages.actions)}
websiteId={websiteId}
onDataLoad={handleDataLoad}
/>
);
}
const Label = ({ value }) => {
const [event, label] = value.split('\t');
return (
<>
<Tag>{event}</Tag>
{label}
</>
);
};

View File

@ -1,6 +0,0 @@
.filter {
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 15px;
}

View File

@ -54,9 +54,12 @@ export default function MetricsTable({
const filteredData = useMemo(() => {
if (data) {
const items = percentFilter(dataFilter ? dataFilter(data, filterOptions) : data);
let items = percentFilter(dataFilter ? dataFilter(data, filterOptions) : data);
if (limit) {
return items.filter((e, i) => i < limit).sort(firstBy('y', -1).thenBy('x'));
items = items.filter((e, i) => i < limit);
}
if (filterOptions?.sort === false) {
return items;
}
return items.sort(firstBy('y', -1).thenBy('x'));
}

View File

@ -0,0 +1,56 @@
import { useState } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import MetricsTable from './MetricsTable';
import Tag from 'components/common/Tag';
import { paramFilter } from 'lib/filters';
import { safeDecodeURI } from 'lib/url';
import FilterButtons from '../common/FilterButtons';
const FILTER_COMBINED = 0;
const FILTER_RAW = 1;
const messages = defineMessages({
combined: { id: 'metrics.filter.combined', defaultMessage: 'Combined' },
raw: { id: 'metrics.filter.raw', defaultMessage: 'Raw' },
views: { id: 'metrics.views', defaultMessage: 'Views' },
none: { id: 'label.none', defaultMessage: 'None' },
query: { id: 'metrics.query-parameters', defaultMessage: 'Query parameters' },
});
export default function QueryParametersTable({ websiteId, showFilters, ...props }) {
const [filter, setFilter] = useState(FILTER_COMBINED);
const { formatMessage } = useIntl();
const buttons = [
{
label: formatMessage(messages.combined),
value: FILTER_COMBINED,
},
{ label: formatMessage(messages.raw), value: FILTER_RAW },
];
return (
<>
{showFilters && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
<MetricsTable
{...props}
title={formatMessage(messages.query)}
type="query"
metric={formatMessage(messages.views)}
websiteId={websiteId}
dataFilter={filter !== FILTER_RAW ? paramFilter : null}
renderLabel={({ x, p, v }) =>
filter === FILTER_RAW ? (
x
) : (
<>
<Tag>{safeDecodeURI(p)}</Tag>
{safeDecodeURI(v)}
</>
)
}
delay={0}
/>
</>
);
}

View File

@ -3,7 +3,6 @@ import { FormattedMessage, useIntl } from 'react-intl';
import { FixedSizeList } from 'react-window';
import firstBy from 'thenby';
import Icon from 'components/common/Icon';
import Tag from 'components/common/Tag';
import Dot from 'components/common/Dot';
import FilterButtons from 'components/common/FilterButtons';
import NoData from 'components/common/NoData';
@ -92,8 +91,7 @@ export default function RealtimeLog({ data, websites, websiteId }) {
}
function getDetail({
event_type,
event_value,
event_name,
view_id,
session_id,
url,
@ -103,12 +101,8 @@ export default function RealtimeLog({ data, websites, websiteId }) {
device,
website_id,
}) {
if (event_type) {
return (
<div>
<Tag>{event_type}</Tag> {event_value}
</div>
);
if (event_name) {
return <div>{event_name}</div>;
}
if (view_id) {
const domain = getWebsite({ website_id })?.domain;

View File

@ -5,8 +5,8 @@ import FilterButtons from 'components/common/FilterButtons';
import FilterLink from 'components/common/FilterLink';
import { refFilter } from 'lib/filters';
export const FILTER_COMBINED = 0;
export const FILTER_RAW = 1;
const FILTER_COMBINED = 0;
const FILTER_RAW = 1;
const messages = defineMessages({
combined: { id: 'metrics.filter.combined', defaultMessage: 'Combined' },

View File

@ -6,7 +6,7 @@ export default function ScreenTable({ websiteId, ...props }) {
return (
<MetricsTable
{...props}
title={<FormattedMessage id="metrics.screens" defaultMessage="Screen" />}
title={<FormattedMessage id="metrics.screens" defaultMessage="Screens" />}
type="screen"
metric={<FormattedMessage id="metrics.visitors" defaultMessage="Visitors" />}
websiteId={websiteId}

View File

@ -1,47 +0,0 @@
import React, { useState } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import MetricsTable from './MetricsTable';
import FilterButtons from 'components/common/FilterButtons';
export const UTM_SOURCE = 'utm_source';
export const UTM_MEDIUM = 'utm_medium';
export const UTM_CAMPAIGN = 'utm_campaign';
export const UTM_CONTENT = 'utm_content';
export const UTM_TERM = 'utm_term';
const messages = defineMessages({
utm_source: { id: 'metrics.utm_source', defaultMessage: 'UTM Source' },
utm_medium: { id: 'metrics.utm_medium', defaultMessage: 'UTM Medium' },
utm_campaign: { id: 'metrics.utm_campaign', defaultMessage: 'UTM Campaign' },
utm_content: { id: 'metrics.utm_content', defaultMessage: 'UTM Content' },
utm_term: { id: 'metrics.utm_term', defaultMessage: 'UTM Term' },
views: { id: 'metrics.views', defaultMessage: 'Views' },
none: { id: 'label.none', defaultMessage: 'None' },
});
export default function UTMTable({ websiteId, showFilters, ...props }) {
const [type, setType] = useState(UTM_SOURCE);
const { formatMessage } = useIntl();
const buttons = [
{ label: formatMessage(messages.utm_source), value: UTM_SOURCE },
{ label: formatMessage(messages.utm_medium), value: UTM_MEDIUM },
{ label: formatMessage(messages.utm_campaign), value: UTM_CAMPAIGN },
{ label: formatMessage(messages.utm_content), value: UTM_CONTENT },
{ label: formatMessage(messages.utm_term), value: UTM_TERM },
];
return (
<>
{showFilters && <FilterButtons buttons={buttons} selected={type} onClick={setType} />}
<MetricsTable
{...props}
title={formatMessage(messages[type])}
type={type}
metric={formatMessage(messages.views)}
websiteId={websiteId}
delay={0}
/>
</>
);
}

View File

@ -1,5 +1,5 @@
import { useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { defineMessages, useIntl } from 'react-intl';
import { useRouter } from 'next/router';
import Page from 'components/layout/Page';
import PageHeader from 'components/layout/PageHeader';
@ -7,19 +7,24 @@ import WebsiteList from 'components/pages/WebsiteList';
import Button from 'components/common/Button';
import DashboardSettingsButton from 'components/settings/DashboardSettingsButton';
import useFetch from 'hooks/useFetch';
import useStore from 'store/app';
import useDashboard from 'store/dashboard';
import DashboardEdit from './DashboardEdit';
import styles from './WebsiteList.module.css';
const selector = state => state.dashboard;
const messages = defineMessages({
dashboard: { id: 'label.dashboard', defaultMessage: 'Dashboard' },
more: { id: 'label.more', defaultMessage: 'More' },
});
export default function Dashboard() {
const router = useRouter();
const { id } = router.query;
const userId = id?.[0];
const store = useStore(selector);
const { showCharts, limit } = store;
const dashboard = useDashboard();
const { showCharts, limit, editing } = dashboard;
const [max, setMax] = useState(limit);
const { data } = useFetch('/websites', { params: { user_id: userId } });
const { formatMessage } = useIntl();
function handleMore() {
setMax(max + limit);
@ -32,15 +37,14 @@ export default function Dashboard() {
return (
<Page>
<PageHeader>
<div>
<FormattedMessage id="label.dashboard" defaultMessage="Dashboard" />
</div>
<DashboardSettingsButton />
<div>{formatMessage(messages.dashboard)}</div>
{!editing && <DashboardSettingsButton />}
</PageHeader>
<WebsiteList websites={data} showCharts={showCharts} limit={max} />
{editing && <DashboardEdit websites={data} />}
{!editing && <WebsiteList websites={data} showCharts={showCharts} limit={max} />}
{max < data.length && (
<Button className={styles.button} onClick={handleMore}>
<FormattedMessage id="label.more" defaultMessage="More" />
{formatMessage(messages.more)}
</Button>
)}
</Page>

View File

@ -0,0 +1,102 @@
import { useState, useMemo } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
import classNames from 'classnames';
import Button from 'components/common/Button';
import { sortArrayByMap } from 'lib/array';
import useDashboard, { saveDashboard } from 'store/dashboard';
import styles from './DashboardEdit.module.css';
const messages = defineMessages({
save: { id: 'label.save', defaultMessage: 'Save' },
reset: { id: 'label.reset', defaultMessage: 'Reset' },
cancel: { id: 'label.cancel', defaultMessage: 'Cancel' },
});
const dragId = 'dashboard-website-ordering';
export default function DashboardEdit({ websites }) {
const settings = useDashboard();
const { websiteOrder } = settings;
const { formatMessage } = useIntl();
const [order, setOrder] = useState(websiteOrder || []);
const ordered = useMemo(() => sortArrayByMap(websites, order, 'website_id'), [websites, order]);
console.log({ order, ordered });
function handleWebsiteDrag({ destination, source }) {
if (!destination || destination.index === source.index) return;
const orderedWebsites = [...ordered];
const [removed] = orderedWebsites.splice(source.index, 1);
orderedWebsites.splice(destination.index, 0, removed);
setOrder(orderedWebsites.map(({ website_id }) => website_id));
}
function handleSave() {
saveDashboard({
editing: false,
websiteOrder: order,
});
}
function handleCancel() {
saveDashboard({ editing: false, websiteOrder });
}
function handleReset() {
setOrder([]);
}
return (
<>
<div className={styles.buttons}>
<Button onClick={handleSave} variant="action" size="small">
{formatMessage(messages.save)}
</Button>
<Button onClick={handleCancel} size="small">
{formatMessage(messages.cancel)}
</Button>
<Button onClick={handleReset} size="small">
{formatMessage(messages.reset)}
</Button>
</div>
<div className={styles.dragActive}>
<DragDropContext onDragEnd={handleWebsiteDrag}>
<Droppable droppableId={dragId}>
{(provided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={{ marginBottom: snapshot.isDraggingOver ? 260 : null }}
>
{ordered.map(({ website_id, name, domain }, index) => (
<Draggable key={website_id} draggableId={`${dragId}-${website_id}`} index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
className={classNames(styles.item, {
[styles.active]: snapshot.isDragging,
})}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<div className={styles.text}>
<h1>{name}</h1>
<h2>{domain}</h2>
</div>
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
</div>
</>
);
}

View File

@ -0,0 +1,40 @@
.buttons {
display: flex;
justify-content: flex-end;
gap: 10px;
margin-bottom: 20px;
}
.item {
padding: 5px 0;
}
.item h1 {
font-weight: 600;
font-size: 16px;
}
.item h2 {
font-size: 14px;
color: var(--gray700);
}
.text {
padding: 20px;
border-radius: 5px;
border: 1px solid var(--gray400);
background: var(--gray50);
}
.active .text {
border-color: var(--gray600);
box-shadow: 4px 4px 4px var(--gray100);
}
.dragActive {
cursor: grab;
}
.dragActive:active {
cursor: grabbing;
}

View File

@ -1,4 +1,3 @@
import React, { useState } from 'react';
import classNames from 'classnames';
import Head from 'next/head';
import Link from 'next/link';
@ -9,35 +8,37 @@ import DropDown from 'components/common/DropDown';
import WebsiteChart from 'components/metrics/WebsiteChart';
import EventsChart from 'components/metrics/EventsChart';
import Button from 'components/common/Button';
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
import Icon from 'components/common/Icon';
import useFetch from 'hooks/useFetch';
import useUser from 'hooks/useUser';
import ChevronDown from 'assets/chevron-down.svg';
import styles from './TestConsole.module.css';
export default function TestConsole() {
const { user } = useUser();
const [website, setWebsite] = useState();
const [show, setShow] = useState(true);
const { basePath } = useRouter();
const { data } = useFetch('/websites');
const router = useRouter();
const {
basePath,
query: { id },
} = router;
const websiteId = id?.[0];
if (!data || !user?.is_admin) {
if (!data) {
return null;
}
const options = data.map(({ name, website_id }) => ({ label: name, value: website_id }));
const website = data.find(({ website_id }) => website_id === +websiteId);
const selectedValue = options.find(({ value }) => value === website?.website_id)?.value;
console.log({ websiteId, data, options, website });
function handleSelect(value) {
setWebsite(data.find(({ website_id }) => website_id === value));
router.push(`/console/${value}`);
}
function handleClick() {
window.umami('event (default)');
window.umami('umami-default');
window.umami.trackView('/page-view', 'https://www.google.com');
window.umami.trackEvent('event (custom)', 'custom-type');
window.umami.trackEvent('track-event-no-data');
window.umami.trackEvent('track-event-with-data', { test: 'test-data', time: Date.now() });
}
return (
@ -61,54 +62,47 @@ export default function TestConsole() {
onChange={handleSelect}
/>
</PageHeader>
{!selectedValue && <EmptyPlaceholder msg="I hope you know what you're doing here" />}
{selectedValue && (
{website && (
<>
<div>
<Icon
icon={<ChevronDown />}
className={classNames({ [styles.hidden]: !show })}
onClick={() => setShow(!show)}
/>
</div>
{show && (
<div className={classNames(styles.test, 'row')}>
<div className="col-4">
<PageHeader>Page links</PageHeader>
<div>
<Link href={`?page=1`}>
<a>page one</a>
</Link>
</div>
<div>
<Link href={`?page=2`}>
<a>page two</a>
</Link>
</div>
<div>
<Link href={`https://www.google.com`}>
<a className="umami--click--external-link">external link</a>
</Link>
</div>
<div className={classNames(styles.test, 'row')}>
<div className="col-4">
<PageHeader>Page links</PageHeader>
<div>
<Link href={`/console/${websiteId}?page=1`}>
<a>page one</a>
</Link>
</div>
<div className="col-4">
<PageHeader>CSS events</PageHeader>
<Button
id="primary-button"
className="umami--click--primary-button"
variant="action"
>
Send event
</Button>
<div>
<Link href={`/console/${websiteId}?page=2`}>
<a>page two</a>
</Link>
</div>
<div className="col-4">
<PageHeader>Javascript events</PageHeader>
<Button id="manual-button" variant="action" onClick={handleClick}>
Run script
</Button>
<div>
<Link href={`https://www.google.com`}>
<a className="umami--click--external-link-direct">external link (direct)</a>
</Link>
</div>
<div>
<Link href={`https://www.google.com`}>
<a className="umami--click--external-link-tab" target="_blank">
external link (tab)
</a>
</Link>
</div>
</div>
)}
<div className="col-4">
<PageHeader>CSS events</PageHeader>
<Button id="primary-button" className="umami--click--button-click" variant="action">
Send event
</Button>
</div>
<div className="col-4">
<PageHeader>Javascript events</PageHeader>
<Button id="manual-button" variant="action" onClick={handleClick}>
Run script
</Button>
</div>
</div>
<div className="row">
<div className="col-12">
<WebsiteChart

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import classNames from 'classnames';
import WebsiteChart from 'components/metrics/WebsiteChart';
import WorldMap from 'components/common/WorldMap';
@ -18,12 +18,25 @@ import CountriesTable from 'components/metrics/CountriesTable';
import LanguagesTable from 'components/metrics/LanguagesTable';
import EventsTable from 'components/metrics/EventsTable';
import EventsChart from 'components/metrics/EventsChart';
import ScreenTable from 'components/metrics/ScreenTable';
import QueryParametersTable from 'components/metrics/QueryParametersTable';
import useFetch from 'hooks/useFetch';
import usePageQuery from 'hooks/usePageQuery';
import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
import styles from './WebsiteDetails.module.css';
import ScreenTable from 'components/metrics/ScreenTable';
import UTMTable from 'components/metrics/UTMTable';
const messages = defineMessages({
pages: { id: 'metrics.pages', defaultMessage: 'Pages' },
referrers: { id: 'metrics.referrers', defaultMessage: 'Referrers' },
screens: { id: 'metrics.screens', defaultMessage: 'Screens' },
browsers: { id: 'metrics.browsers', defaultMessage: 'Browsers' },
os: { id: 'metrics.operating-systems', defaultMessage: 'Operating system' },
devices: { id: 'metrics.devices', defaultMessage: 'Devices' },
countries: { id: 'metrics.countries', defaultMessage: 'Countries' },
languages: { id: 'metrics.languages', defaultMessage: 'Languages' },
events: { id: 'metrics.events', defaultMessage: 'Events' },
query: { id: 'metrics.query-parameters', defaultMessage: 'Query parameters' },
});
const views = {
url: PagesTable,
@ -35,7 +48,7 @@ const views = {
country: CountriesTable,
language: LanguagesTable,
event: EventsTable,
utm: UTMTable,
query: QueryParametersTable,
};
export default function WebsiteDetails({ websiteId }) {
@ -47,6 +60,7 @@ export default function WebsiteDetails({ websiteId }) {
resolve,
query: { view },
} = usePageQuery();
const { formatMessage } = useIntl();
const BackButton = () => (
<div key="back-button" className={classNames(styles.backButton, 'col-12')}>
@ -61,44 +75,44 @@ export default function WebsiteDetails({ websiteId }) {
render: BackButton,
},
{
label: <FormattedMessage id="metrics.pages" defaultMessage="Pages" />,
label: formatMessage(messages.pages),
value: resolve({ view: 'url' }),
},
{
label: <FormattedMessage id="metrics.referrers" defaultMessage="Referrers" />,
label: formatMessage(messages.referrers),
value: resolve({ view: 'referrer' }),
},
{
label: <FormattedMessage id="metrics.screens" defaultMessage="Screens" />,
value: resolve({ view: 'screen' }),
},
{
label: <FormattedMessage id="metrics.browsers" defaultMessage="Browsers" />,
label: formatMessage(messages.browsers),
value: resolve({ view: 'browser' }),
},
{
label: <FormattedMessage id="metrics.operating-systems" defaultMessage="Operating system" />,
label: formatMessage(messages.os),
value: resolve({ view: 'os' }),
},
{
label: <FormattedMessage id="metrics.devices" defaultMessage="Devices" />,
label: formatMessage(messages.devices),
value: resolve({ view: 'device' }),
},
{
label: <FormattedMessage id="metrics.countries" defaultMessage="Countries" />,
label: formatMessage(messages.countries),
value: resolve({ view: 'country' }),
},
{
label: <FormattedMessage id="metrics.languages" defaultMessage="Languages" />,
label: formatMessage(messages.languages),
value: resolve({ view: 'language' }),
},
{
label: <FormattedMessage id="metrics.events" defaultMessage="Events" />,
label: formatMessage(messages.screens),
value: resolve({ view: 'screen' }),
},
{
label: formatMessage(messages.events),
value: resolve({ view: 'event' }),
},
{
label: <FormattedMessage id="metrics.utm" defaultMessage="UTM" />,
value: resolve({ view: 'utm' }),
label: formatMessage(messages.query),
value: resolve({ view: 'query' }),
},
];

View File

@ -1,25 +1,42 @@
import { FormattedMessage } from 'react-intl';
import { defineMessages, useIntl } from 'react-intl';
import Link from 'components/common/Link';
import WebsiteChart from 'components/metrics/WebsiteChart';
import Page from 'components/layout/Page';
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
import Arrow from 'assets/arrow-right.svg';
import styles from './WebsiteList.module.css';
import useDashboard from 'store/dashboard';
import { sortArrayByMap } from 'lib/array';
import { useMemo } from 'react';
const messages = defineMessages({
noWebsites: {
id: 'message.no-websites-configured',
defaultMessage: "You don't have any websites configured.",
},
goToSettngs: {
id: 'message.go-to-settings',
defaultMessage: 'Go to settings',
},
});
export default function WebsiteList({ websites, showCharts, limit }) {
const { websiteOrder } = useDashboard();
const { formatMessage } = useIntl();
console.log({ websiteOrder });
const ordered = useMemo(
() => sortArrayByMap(websites, websiteOrder, 'website_id'),
[websites, websiteOrder],
);
if (websites.length === 0) {
return (
<Page>
<EmptyPlaceholder
msg={
<FormattedMessage
id="message.no-websites-configured"
defaultMessage="You don't have any websites configured."
/>
}
>
<EmptyPlaceholder msg={formatMessage(messages.noWebsites)}>
<Link href="/settings" icon={<Arrow />} iconRight>
<FormattedMessage id="message.go-to-settings" defaultMessage="Go to settings" />
{formatMessage(messages.goToSettngs)}
</Link>
</EmptyPlaceholder>
</Page>
@ -28,7 +45,7 @@ export default function WebsiteList({ websites, showCharts, limit }) {
return (
<div>
{websites.map(({ website_id, name, domain }, index) =>
{ordered.map(({ website_id, name, domain }, index) =>
index < limit ? (
<div key={website_id} className={styles.website}>
<WebsiteChart

View File

@ -1,26 +1,35 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { defineMessages, useIntl } from 'react-intl';
import MenuButton from 'components/common/MenuButton';
import Gear from 'assets/gear.svg';
import useStore, { setDashboard, defaultDashboardConfig } from 'store/app';
import { saveDashboard } from 'store/dashboard';
const selector = state => state.dashboard;
const messages = defineMessages({
toggleCharts: { id: 'message.toggle-charts', defaultMessage: 'Toggle charts' },
editDashboard: { id: 'message.edit-dashboard', defaultMessage: 'Edit dashboard' },
});
export default function DashboardSettingsButton() {
const settings = useStore(selector);
const { formatMessage } = useIntl();
const menuOptions = [
{
label: <FormattedMessage id="message.toggle-charts" defaultMessage="Toggle charts" />,
label: formatMessage(messages.toggleCharts),
value: 'charts',
},
{
label: formatMessage(messages.editDashboard),
value: 'order',
},
];
function handleSelect(value) {
if (value === 'charts') {
setDashboard({ ...defaultDashboardConfig, showCharts: !settings.showCharts });
saveDashboard(state => ({ showCharts: !state.showCharts }));
}
if (value === 'order') {
saveDashboard({ editing: true });
}
//setDashboard(value);
}
return <MenuButton icon={<Gear />} options={menuOptions} onSelect={handleSelect} hideLabel />;

View File

@ -0,0 +1,5 @@
.buttonGroup {
display: flex;
place-items: center;
gap: 10px;
}

View File

@ -36,6 +36,7 @@ export default function WebsiteSettings() {
const [showUrl, setShowUrl] = useState();
const [saved, setSaved] = useState(0);
const [message, setMessage] = useState();
const { data } = useFetch('/websites', { params: { include_all: !!user?.is_admin } }, [saved]);
const Buttons = row => (

View File

@ -0,0 +1,62 @@
-- DropForeignKey
ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_1`;
ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_2`;
DROP INDEX `event_created_at_idx` ON `event`;
DROP INDEX `event_session_id_idx` ON `event`;
DROP INDEX `event_website_id_idx` ON `event`;
CREATE INDEX `event_old_created_at_idx` ON `event` (created_at);
CREATE INDEX `event_old_session_id_idx` ON `event` (session_id);
CREATE INDEX `event_old_website_id_idx` ON `event` (website_id);
-- RenameTable
RENAME TABLE `event` TO `_event_old`;
-- CreateTable
CREATE TABLE `event`
(
`event_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`website_id` INTEGER UNSIGNED NOT NULL,
`session_id` INTEGER UNSIGNED NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
`url` VARCHAR(500) NOT NULL,
`event_name` VARCHAR(50) NOT NULL,
INDEX `event_created_at_idx`(`created_at`),
INDEX `event_session_id_idx`(`session_id`),
INDEX `event_website_id_idx`(`website_id`),
PRIMARY KEY (`event_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_2` FOREIGN KEY (`session_id`) REFERENCES `session`(`session_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
-- AddForeignKey
ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_1` FOREIGN KEY (`website_id`) REFERENCES `website`(`website_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
-- CreateTable
CREATE TABLE `event_data` (
`event_data_id` INTEGER NOT NULL AUTO_INCREMENT,
`event_id` INTEGER UNSIGNED NOT NULL,
`event_data` JSON NOT NULL,
UNIQUE INDEX `event_data_event_id_key`(`event_id`),
PRIMARY KEY (`event_data_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `event_data` ADD CONSTRAINT `event_data_event_id_fkey` FOREIGN KEY (`event_id`) REFERENCES `event`(`event_id`) ON DELETE RESTRICT ON UPDATE CASCADE;
-- RenameIndex
ALTER TABLE `account` RENAME INDEX `username` TO `account_username_key`;
-- RenameIndex
ALTER TABLE `session` RENAME INDEX `session_uuid` TO `session_session_uuid_key`;
-- RenameIndex
ALTER TABLE `website` RENAME INDEX `share_id` TO `website_share_id_key`;
-- RenameIndex
ALTER TABLE `website` RENAME INDEX `website_uuid` TO `website_website_uuid_key`;

View File

@ -9,7 +9,7 @@ datasource db {
model account {
user_id Int @id @default(autoincrement()) @db.UnsignedInt
username String @unique(map: "username") @db.VarChar(255)
username String @unique() @db.VarChar(255)
password String @db.VarChar(60)
is_admin Boolean @default(false)
created_at DateTime? @default(now()) @db.Timestamp(0)
@ -18,21 +18,28 @@ model account {
}
model event {
event_id Int @id @default(autoincrement()) @db.UnsignedInt
website_id Int @db.UnsignedInt
session_id Int @db.UnsignedInt
created_at DateTime? @default(now()) @db.Timestamp(0)
url String @db.VarChar(500)
event_type String @db.VarChar(50)
event_value String @db.VarChar(50)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2")
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1")
event_id Int @id @default(autoincrement()) @db.UnsignedInt
website_id Int @db.UnsignedInt
session_id Int @db.UnsignedInt
created_at DateTime? @default(now()) @db.Timestamp(0)
url String @db.VarChar(500)
event_name String @db.VarChar(50)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2")
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1")
event_data event_data?
@@index([created_at])
@@index([session_id])
@@index([website_id])
}
model event_data {
event_data_id Int @id @default(autoincrement())
event_id Int @unique @db.UnsignedInt
event_data Json
event event @relation(fields: [event_id], references: [event_id])
}
model pageview {
view_id Int @id @default(autoincrement()) @db.UnsignedInt
website_id Int @db.UnsignedInt
@ -52,7 +59,7 @@ model pageview {
model session {
session_id Int @id @default(autoincrement()) @db.UnsignedInt
session_uuid String @unique(map: "session_uuid") @db.VarChar(36)
session_uuid String @unique() @db.VarChar(36)
website_id Int @db.UnsignedInt
created_at DateTime? @default(now()) @db.Timestamp(0)
hostname String? @db.VarChar(100)
@ -72,11 +79,11 @@ model session {
model website {
website_id Int @id @default(autoincrement()) @db.UnsignedInt
website_uuid String @unique(map: "website_uuid") @db.VarChar(36)
website_uuid String @unique() @db.VarChar(36)
user_id Int @db.UnsignedInt
name String @db.VarChar(100)
domain String? @db.VarChar(500)
share_id String? @unique(map: "share_id") @db.VarChar(64)
share_id String? @unique() @db.VarChar(64)
created_at DateTime? @default(now()) @db.Timestamp(0)
account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade, onUpdate: NoAction, map: "website_ibfk_1")
event event[]

View File

@ -0,0 +1,66 @@
-- DropForeignKey
ALTER TABLE "event" DROP CONSTRAINT "event_session_id_fkey";
ALTER TABLE "event" DROP CONSTRAINT "event_website_id_fkey";
-- RenameIndex
ALTER INDEX "event_pkey" RENAME TO "event_old_pkey";
ALTER INDEX "event_created_at_idx" RENAME TO "event_old_created_at_idx";
ALTER INDEX "event_session_id_idx" RENAME TO "event_old_session_id_idx";
ALTER INDEX "event_website_id_idx" RENAME TO "event_old_website_id_idx";
-- RenameTable
ALTER TABLE "event" RENAME TO "_event_old";
-- CreateTable
CREATE TABLE "event" (
"event_id" SERIAL NOT NULL,
"website_id" INTEGER NOT NULL,
"session_id" INTEGER NOT NULL,
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
"url" VARCHAR(500) NOT NULL,
"event_name" VARCHAR(50) NOT NULL,
PRIMARY KEY ("event_id")
);
-- CreateIndex
CREATE INDEX "event_created_at_idx" ON "event"("created_at");
-- CreateIndex
CREATE INDEX "event_session_id_idx" ON "event"("session_id");
-- CreateIndex
CREATE INDEX "event_website_id_idx" ON "event"("website_id");
-- AddForeignKey
ALTER TABLE "event" ADD CONSTRAINT "event_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "event" ADD CONSTRAINT "event_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE "event_data" (
"event_data_id" SERIAL NOT NULL,
"event_id" INTEGER NOT NULL,
"event_data" JSONB NOT NULL,
CONSTRAINT "event_data_pkey" PRIMARY KEY ("event_data_id")
);
-- CreateIndex
CREATE UNIQUE INDEX "event_data_event_id_key" ON "event_data"("event_id");
-- AddForeignKey
ALTER TABLE "event_data" ADD CONSTRAINT "event_data_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "event"("event_id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- RenameIndex
ALTER INDEX "account.username_unique" RENAME TO "account_username_key";
-- RenameIndex
ALTER INDEX "session.session_uuid_unique" RENAME TO "session_session_uuid_key";
-- RenameIndex
ALTER INDEX "website.share_id_unique" RENAME TO "website_share_id_key";
-- RenameIndex
ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key";

View File

@ -18,21 +18,28 @@ model account {
}
model event {
event_id Int @id @default(autoincrement())
website_id Int
session_id Int
created_at DateTime? @default(now()) @db.Timestamptz(6)
url String @db.VarChar(500)
event_type String @db.VarChar(50)
event_value String @db.VarChar(50)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction)
event_id Int @id @default(autoincrement())
website_id Int
session_id Int
created_at DateTime? @default(now()) @db.Timestamptz(6)
url String @db.VarChar(500)
event_name String @db.VarChar(50)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
event_data event_data?
@@index([created_at])
@@index([session_id])
@@index([website_id])
}
model event_data {
event_data_id Int @id @default(autoincrement())
event_id Int @unique
event_data Json
event event @relation(fields: [event_id], references: [event_id])
}
model pageview {
view_id Int @id @default(autoincrement())
website_id Int
@ -40,8 +47,8 @@ model pageview {
created_at DateTime? @default(now()) @db.Timestamptz(6)
url String @db.VarChar(500)
referrer String? @db.VarChar(500)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction)
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
@@index([created_at])
@@index([session_id])
@ -58,13 +65,13 @@ model session {
hostname String? @db.VarChar(100)
browser String? @db.VarChar(20)
os String? @db.VarChar(20)
device String? @db.VarChar(20)
screen String? @db.VarChar(11)
language String? @db.VarChar(35)
country String? @db.Char(2)
device String? @db.VarChar(20)
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction)
event event[]
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
pageview pageview[]
event event[]
@@index([created_at])
@@index([website_id])
@ -73,15 +80,15 @@ model session {
model website {
website_id Int @id @default(autoincrement())
website_uuid String @unique @db.Uuid
name String @db.VarChar(100)
created_at DateTime? @default(now()) @db.Timestamptz(6)
user_id Int
name String @db.VarChar(100)
domain String? @db.VarChar(500)
share_id String? @unique(map: "website_share_id_idx") @db.VarChar(64)
account account @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction)
event event[]
share_id String? @unique @db.VarChar(64)
created_at DateTime? @default(now()) @db.Timestamptz(6)
account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade)
pageview pageview[]
session session[]
event event[]
@@index([user_id])
}

View File

@ -6,7 +6,7 @@ import useStore from 'store/app';
const selector = state => state.shareToken;
function parseHeaders(headers = {}, { authToken, shareToken }) {
function parseHeaders(headers, { authToken, shareToken }) {
if (authToken) {
headers.authorization = `Bearer ${authToken}`;
}
@ -25,7 +25,7 @@ export default function useApi() {
return {
get: useCallback(
async (url, params, headers) => {
async (url, params = {}, headers = {}) => {
return get(
`${basePath}/api${url}`,
params,
@ -36,7 +36,7 @@ export default function useApi() {
),
post: useCallback(
async (url, params, headers) => {
async (url, params = {}, headers = {}) => {
return post(
`${basePath}/api${url}`,
params,
@ -47,7 +47,7 @@ export default function useApi() {
),
put: useCallback(
async (url, params, headers) => {
async (url, params = {}, headers = {}) => {
return put(
`${basePath}/api${url}`,
params,
@ -58,7 +58,7 @@ export default function useApi() {
),
del: useCallback(
async (url, params, headers) => {
async (url, params = {}, headers = {}) => {
return del(
`${basePath}/api${url}`,
params,

24
hooks/useConfig.js Normal file
View File

@ -0,0 +1,24 @@
import { useEffect } from 'react';
import useStore, { setConfig } from 'store/app';
import useApi from 'hooks/useApi';
let fetched = false;
export default function useConfig() {
const { config } = useStore();
const { get } = useApi();
async function loadConfig() {
const { data } = await get('/config');
setConfig(data);
}
useEffect(() => {
if (!config && !fetched) {
fetched = true;
loadConfig();
}
}, []);
return config || {};
}

View File

@ -8,7 +8,9 @@
"metrics.device.desktop",
"metrics.device.laptop",
"metrics.device.tablet",
"metrics.referrers"
"metrics.referrers",
"metrics.utm",
"metrics.utm_medium"
],
"en-GB": "*",
"fr-FR": ["metrics.actions", "metrics.pages"],
@ -34,5 +36,10 @@
"metrics.device.desktop",
"metrics.device.tablet",
"metrics.filter.raw"
],
"pt-PT": [
"label.websites",
"metrics.device.desktop",
"metrics.device.tablet"
]
}

View File

@ -4,7 +4,6 @@
"label.add-website": "إضافة موقع",
"label.administrator": "مدير عام؟",
"label.all": "الكل",
"label.all-events": "كافة الأحداث",
"label.all-time": "All time",
"label.all-websites": "كافة المواقع",
"label.back": "للخلف",
@ -68,6 +67,7 @@
"message.confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟",
"message.copied": "تم النسخ!",
"message.delete-warning": "كافة البيانات المرتبطة سيم حذفها ايضا.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "حدث خطأ ما.",
"message.get-share-url": "احصل على رابط المشاركة",
"message.get-tracking-code": "احصل على كود التتبع",
@ -103,15 +103,10 @@
"metrics.operating-systems": "نظام التشغيل",
"metrics.page-views": "مشاهدات الصفحة",
"metrics.pages": "الصفحات",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "التحويلات",
"metrics.screens": "Screens",
"metrics.unique-visitors": "زائرون فريدون",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "مشاهدات",
"metrics.visitors": "زوار"
}

112
lang/bn-BD.json Normal file
View File

@ -0,0 +1,112 @@
{
"label.accounts": "অ্যাকাউন্ট",
"label.add-account": "অ্যাকাউন্ট যুক্ত করুন",
"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": "শেয়ার ইউআরএল শেয়ার করুন",
"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.settings": "সেটিংস",
"label.share-url": "ইউআরএল শেয়ার করুন",
"label.single-day": "একদিন",
"label.theme": "থিম",
"label.this-month": "এই মাস",
"label.this-week": "এই সপ্তাহ",
"label.this-year": "এই বছর",
"label.timezone": "সময়স্থান",
"label.today": "আজ",
"label.tracking-code": "ট্র্যাকিং কোড",
"label.unknown": "অজানা",
"label.username": "ব্যবহারকারীর নাম",
"label.view-details": "বিস্তারিত দেখুন",
"label.websites": "সবগুলো ওয়েবসাইট",
"message.active-users": "{x} বর্তমান {x, plural, one {visitor} other {visitors}}",
"message.confirm-delete": "আপনি কি নিশ্চিত যে আপনি {target} মুছতে চান?",
"message.confirm-reset": "আপনি কি নিশ্চিত যে আপনি {target} এর পরিসংখ্যান পুনরায় সেট করতে চান?",
"message.copied": "কপি হয়েছে",
"message.delete-warning": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "কিছু ভুল হয়েছে।",
"message.get-share-url": "শেয়ার ইউআরএল",
"message.get-tracking-code": "ট্র্যাকিং কোড পান",
"message.go-to-settings": "সেটিংস এ যান",
"message.incorrect-username-password": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।",
"message.log.visitor": "{country} থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন {os} {device} এর মধ্যে।",
"message.new-version-available": "নতুন সংস্করণ {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} এর জন্য প্রকাশ্যে শেয়ার করার ইউআরএল।",
"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": "Query parameters",
"metrics.referrers": "রেফারার্স",
"metrics.screens": "স্ক্রিনগুলি",
"metrics.unique-visitors": "অনন্য ভিজিটর",
"metrics.views": "ভিউস",
"metrics.visitors": "পরিদর্শনার্থী"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Afegeix lloc web",
"label.administrator": "Administrador",
"label.all": "Tots",
"label.all-events": "Tots els esdeveniments",
"label.all-time": "Sempre",
"label.all-websites": "Tots els llocs web",
"label.back": "Enrere",
@ -68,6 +67,7 @@
"message.confirm-reset": "Segur que vols restablir les estadístiques de {target}?",
"message.copied": "S'ha copiat",
"message.delete-warning": "També s'esborraran totes les dades relacionades.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "S'ha produït un error.",
"message.get-share-url": "Obté l'enllaç per compartir",
"message.get-tracking-code": "Obté el codi de seguiment",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemes operatius",
"metrics.page-views": "Pàgines vistes",
"metrics.pages": "Pàgines",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referents",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Visitants únics",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vistes",
"metrics.visitors": "Visitants"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Přidat web",
"label.administrator": "Administrátor",
"label.all": "Vše",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "Všechny weby",
"label.back": "Zpět",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Zkopírováno!",
"message.delete-warning": "Všechna související data budou také smazána.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Něco se pokazilo.",
"message.get-share-url": "Získat sdílené URL",
"message.get-tracking-code": "Získat měřící kód",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operační systém",
"metrics.page-views": "Zobrazení stránek",
"metrics.pages": "Stránky",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Odkazy",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Jedinečné návštěvy",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Zobrazení",
"metrics.visitors": "Návštěvy"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Tilføj hjemmeside",
"label.administrator": "Administrator",
"label.all": "Alle",
"label.all-events": "Alle hændelser",
"label.all-time": "Altid",
"label.all-websites": "Alle hjemmesider",
"label.back": "Tilbage",
@ -68,6 +67,7 @@
"message.confirm-reset": "Er du sikker på at du ville nulstille {target}'s statistikker?",
"message.copied": "Kopieret!",
"message.delete-warning": "Alle tilknyttede data slettes også.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Noget gik galt.",
"message.get-share-url": "Få delings-URL",
"message.get-tracking-code": "Få sporingskode",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operativsystemer",
"metrics.page-views": "Sidevisninger",
"metrics.pages": "Sider",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Henvisninger",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Unikke besøgende",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visninger",
"metrics.visitors": "Besøgende"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Webseite hinzufügen",
"label.administrator": "Administrator",
"label.all": "Alle",
"label.all-events": "Alle Ereignisse",
"label.all-time": "Gesamter Zeitraum",
"label.all-websites": "Alle Webseiten",
"label.back": "Zurück",
@ -37,7 +36,7 @@
"label.more": "Mehr",
"label.name": "Name",
"label.new-password": "Neues Passwort",
"label.none": "None",
"label.none": "Keine",
"label.owner": "Besitzer",
"label.password": "Passwort",
"label.passwords-dont-match": "Passwörter stimmen nicht überein",
@ -68,6 +67,7 @@
"message.confirm-reset": "Sind Sie sicher, dass Sie die Statistiken von {target} zurücksetzen wollen?",
"message.copied": "In Zwischenablage kopiert!",
"message.delete-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Es ist ein Fehler aufgetreten.",
"message.get-share-url": "Freigabe-URL abrufen",
"message.get-tracking-code": "Erstelle Tracking Kennung",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Betriebssysteme",
"metrics.page-views": "Seitenaufrufe",
"metrics.pages": "Seiten",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrer",
"metrics.screens": "Bildschirmauflösungen",
"metrics.unique-visitors": "Eindeutige Besucher",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Aufrufe",
"metrics.visitors": "Besucher"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Προσθήκη ιστότοπου",
"label.administrator": "Διαχειριστής",
"label.all": "All",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "All websites",
"label.back": "Πίσω",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Αντιγράφηκε!",
"message.delete-warning": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Κάτι πήγε στραβά.",
"message.get-share-url": "Λήψη URL κοινής χρήσης",
"message.get-tracking-code": "Λήψη κώδικα παρακολούθησης",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Λειτουργικά συστήματα",
"metrics.page-views": "Προβολές σελίδας",
"metrics.pages": "Σελίδες",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Παραπομπές",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Μοναδικοί επισκέπτες",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Προβολές",
"metrics.visitors": "Επισκέπτες"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Add website",
"label.administrator": "Administrator",
"label.all": "All",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "All websites",
"label.back": "Back",
@ -68,6 +67,7 @@
"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",
@ -103,15 +103,10 @@
"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.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Views",
"metrics.visitors": "Visitors"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Add website",
"label.administrator": "Administrator",
"label.all": "All",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "All websites",
"label.back": "Back",
@ -68,6 +67,7 @@
"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",
@ -103,15 +103,10 @@
"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.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Views",
"metrics.visitors": "Visitors"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Agregar sitio",
"label.administrator": "Administrador",
"label.all": "Todos",
"label.all-events": "Todos los eventos",
"label.all-time": "Todos los tiempos",
"label.all-websites": "Todos los sitios",
"label.back": "Atrás",
@ -68,6 +67,7 @@
"message.confirm-reset": "¿Seguro que deseas restablecer las estadísticas de {target}?",
"message.copied": "¡Copiado!",
"message.delete-warning": "Toda la información relacionada será eliminada.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Algo falló.",
"message.get-share-url": "Obtener URL para compartir",
"message.get-tracking-code": "Obtener código de rastreo",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operativos",
"metrics.page-views": "Vistas",
"metrics.pages": "Páginas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referentes",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vistas",
"metrics.visitors": "Visitantes"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "افزودن وب‌سایت",
"label.administrator": "مدیر",
"label.all": "همه",
"label.all-events": "همه‌ی رویدادها",
"label.all-time": "همه زمان",
"label.all-websites": "همه‌ی وب‌سایت‌ها",
"label.back": "برگشت",
@ -68,6 +67,7 @@
"message.confirm-reset": "آیا از بازنشانی آمار {target} مطمئن هستید?",
"message.copied": "کپی شد!",
"message.delete-warning": "همه‌ی داده‌های مرتبط هم حذف خواهد شد.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "مشکلی پیش آمده است.",
"message.get-share-url": "دریافت URL برای اشتراک گذاری",
"message.get-tracking-code": "گرفتن کد رهگیری",
@ -103,15 +103,10 @@
"metrics.operating-systems": "سیستم‌عامل‌ها",
"metrics.page-views": "بازدید صفحه",
"metrics.pages": "صفحه‌ها",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "ارجاع دهندگان",
"metrics.screens": "Screens",
"metrics.unique-visitors": "بازدیدکننده‌های یکتا",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "بازدید",
"metrics.visitors": "بازدیدکننده"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Lisää verkkosivu",
"label.administrator": "Järjestelmänvalvoja",
"label.all": "Kaikki",
"label.all-events": "Kaikki tapahtumat",
"label.all-time": "Alusta lähtien",
"label.all-websites": "Kaikki verkkosivut",
"label.back": "Takaisin",
@ -68,6 +67,7 @@
"message.confirm-reset": "Haluatko varmasti poistaa sivuston {target} tilastot?",
"message.copied": "Kopioitu!",
"message.delete-warning": "Kaikki siihen liittyvät tiedot poistetaan.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Jotain meni pieleen.",
"message.get-share-url": "Hanki jakamisen URL-osoite",
"message.get-tracking-code": "Hanki seurantakoodi",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Käyttöjärjestelmät",
"metrics.page-views": "Sivun näyttökerrat",
"metrics.pages": "Sivut",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Viittaajat",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Yksittäiset kävijät",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Näyttökerrat",
"metrics.visitors": "Vierailijat"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Legg heimasíðu afturat",
"label.administrator": "Fyrisitari",
"label.all": "Alt",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "Allar heimasíður",
"label.back": "Aftur",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Avrita!",
"message.delete-warning": "Øll data ið er knýtt at verður eisini strika.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Okkurt bleiv gali.",
"message.get-share-url": "Fá leinku sum tú kanst deila",
"message.get-tracking-code": "Fá sporings kotu",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Stýrikervir",
"metrics.page-views": "Opnaðar síðir",
"metrics.pages": "Síðir",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Framsendingar",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Einsýna vitjanir",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Sýningar",
"metrics.visitors": "Vitjandi"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Ajouter un site",
"label.administrator": "Administrateur",
"label.all": "Tout",
"label.all-events": "Tous les événements",
"label.all-time": "Toutes les données",
"label.all-websites": "Tous les sites web",
"label.back": "Retour",
@ -68,6 +67,7 @@
"message.confirm-reset": "Êtes-vous sûr de vouloir réinistialiser les statistiques de {target} ?",
"message.copied": "Copié !",
"message.delete-warning": "Toutes les données associées seront également supprimées.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Un problème est survenu.",
"message.get-share-url": "Obtenir l'URL de partage",
"message.get-tracking-code": "Obtenir le code de suivi",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Systèmes d'exploitation",
"metrics.page-views": "Pages vues",
"metrics.pages": "Pages",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Sources",
"metrics.screens": "Tailles d'écran",
"metrics.unique-visitors": "Visiteurs uniques",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vues",
"metrics.visitors": "Visiteurs"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Engadir sitio web",
"label.administrator": "Administradora",
"label.all": "Todo",
"label.all-events": "Tódolos eventos",
"label.all-time": "Sempre",
"label.all-websites": "Tódolos sitios web",
"label.back": "Atrás",
@ -68,6 +67,7 @@
"message.confirm-reset": "Tes a certeza de querer restablecer as estatísticas de {target}?",
"message.copied": "Copiado!",
"message.delete-warning": "Tamén serán borrados tódolos datos asociados.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Houbo un fallo.",
"message.get-share-url": "Obter URL de compartición",
"message.get-tracking-code": "Obter código de seguimento",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operativos",
"metrics.page-views": "Vistas de páxinas",
"metrics.pages": "Páxinas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Orixes",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Visitas únicas",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizacións",
"metrics.visitors": "Visitantes"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "הוספת אתר",
"label.administrator": "מנהל",
"label.all": "הכל",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "כל האתרים",
"label.back": "חזרה",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "הועתק!",
"message.delete-warning": "כל המידע המקושר יימחק",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "משהו השתבש",
"message.get-share-url": "קבלת URL שיתוף",
"message.get-tracking-code": "קבלת קוד מעקב",
@ -103,15 +103,10 @@
"metrics.operating-systems": "מערכות הפעלה",
"metrics.page-views": "צפיות בדפים",
"metrics.pages": "דפים",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "מפנים",
"metrics.screens": "Screens",
"metrics.unique-visitors": "מבקרים ייחודיים",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "צפיות",
"metrics.visitors": "מבקרים"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "वेबसाइट",
"label.administrator": "प्रशासक",
"label.all": "सब",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "सभी वेबसाइटें",
"label.back": "पीछे",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "कॉपी हो गया!",
"message.delete-warning": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "कुछ गलत हो गया।",
"message.get-share-url": "शेयर URL प्राप्त करें",
"message.get-tracking-code": "ट्रैकिंग कोड प्राप्त करें",
@ -103,15 +103,10 @@
"metrics.operating-systems": "ऑपरेटिंग सिस्टम",
"metrics.page-views": "पृष्ठ दृश्य",
"metrics.pages": "पृष्ठों",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "सन्दर्भदाता",
"metrics.screens": "Screens",
"metrics.unique-visitors": "अद्वितीय आगंतुकों",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "दृश्य",
"metrics.visitors": "आगंतुकों"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Weboldal hozzáadása",
"label.administrator": "Adminisztrátor",
"label.all": "Összes",
"label.all-events": "Összes esemény",
"label.all-time": "All time",
"label.all-websites": "Összes weboldal",
"label.back": "Vissza",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Kimásolva!",
"message.delete-warning": "Minden társított adat törlésre kerül.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Valami baj történt.",
"message.get-share-url": "Megosztási URL kimásolása",
"message.get-tracking-code": "Követési kód kimásolása",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operációs rendszerek",
"metrics.page-views": "Oldalmegtekintések",
"metrics.pages": "Oldalak",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Hivatkozók",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Egyedi látogatók",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Megtekintések",
"metrics.visitors": "Látogatók"
}

View File

@ -4,8 +4,7 @@
"label.add-website": "Tambah situs web",
"label.administrator": "Pengelola",
"label.all": "Semua",
"label.all-events": "Semua peristiwa",
"label.all-time": "All time",
"label.all-time": "Semua waktu",
"label.all-websites": "Semua website",
"label.back": "Kembali",
"label.cancel": "Batal",
@ -28,7 +27,7 @@
"label.enable-share-url": "Aktifkan URL berbagi",
"label.invalid": "Tidak valid",
"label.invalid-domain": "Domain tidak valid",
"label.language": "Language",
"label.language": "Bahasa",
"label.last-days": "{x} hari terakhir",
"label.last-hours": "{x} jam terakhir",
"label.logged-in-as": "Masuk sebagai {username}",
@ -38,7 +37,7 @@
"label.name": "Nama",
"label.new-password": "Kata sandi baru",
"label.none": "None",
"label.owner": "Owner",
"label.owner": "Pemilik",
"label.password": "Kata sandi",
"label.passwords-dont-match": "Kata sandi tidak cocok",
"label.profile": "Profil",
@ -52,7 +51,7 @@
"label.settings": "Pengaturan",
"label.share-url": "Bagikan URL",
"label.single-day": "Sehari",
"label.theme": "Theme",
"label.theme": "Tema",
"label.this-month": "Bulan ini",
"label.this-week": "Minggu ini",
"label.this-year": "Tahun ini",
@ -65,9 +64,10 @@
"label.websites": "Situs web",
"message.active-users": "{x} pengunjung saat ini",
"message.confirm-delete": "Apakah kamu yakin ingin menghapus {target}?",
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.confirm-reset": "Anda yakin ingin mengatur ulang statistik {target}?",
"message.copied": "Tersalin!",
"message.delete-warning": "Semua data terkait juga akan dihapus.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ada yang salah.",
"message.get-share-url": "Dapatkan URL berbagi",
"message.get-tracking-code": "Dapatkan kode pelacakan",
@ -82,8 +82,8 @@
"message.reset-warning": "Semua statistik pada website ini akan dihapus, tetapi kode lacak akan tetap terpasang",
"message.save-success": "Berhasil disimpan.",
"message.share-url": "Ini adalah URL yang dibagikan secara publik untuk {target}.",
"message.toggle-charts": "Toggle charts",
"message.track-stats": "Untuk melacak statistik {target}, tempatkan kode berikut di bagian {head} situs web anda.",
"message.toggle-charts": "Buka grafik",
"message.track-stats": "Untuk melacak statistik {target}, tempatkan kode berikut di bagian {head} situs web nda.",
"message.type-delete": "Ketikkan {delete} pada kotak di bawah untuk konfirmasi.",
"message.type-reset": "Ketikkan {reset} pada kotak di bawah untuk konfirmasi.",
"metrics.actions": "Aksi",
@ -99,19 +99,14 @@
"metrics.events": "Perihal",
"metrics.filter.combined": "Gabungan",
"metrics.filter.raw": "Mentah",
"metrics.languages": "Languages",
"metrics.languages": "Bahasa",
"metrics.operating-systems": "Sistem Operasi",
"metrics.page-views": "Tampilan halaman",
"metrics.pages": "Halaman",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Perujuk",
"metrics.screens": "Screens",
"metrics.screens": "Layar",
"metrics.unique-visitors": "Pengunjung unik",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Tampilan",
"metrics.visitors": "Pengunjung"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Aggiungi sito",
"label.administrator": "Amministratore",
"label.all": "Tutto",
"label.all-events": "Tutti gli eventi",
"label.all-time": "Sempre",
"label.all-websites": "Tutti i siti web",
"label.back": "Indietro",
@ -68,6 +67,7 @@
"message.confirm-reset": "Sei sicuro di voler azzerare le statistiche di {target}?",
"message.copied": "Copiato!",
"message.delete-warning": "Saranno eliminati anche tutti i dati associati.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Si è verificato un errore.",
"message.get-share-url": "Ottieni l'URL di condivisione",
"message.get-tracking-code": "Ottieni il codice di tracking",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemi operativi",
"metrics.page-views": "Visualizzazioni di pagina",
"metrics.pages": "Pagine",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrers",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Visitatori unici",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizzazioni",
"metrics.visitors": "Visitatori"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Webサイトの追加",
"label.administrator": "管理者",
"label.all": "すべて表示",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "すべてのWebサイト",
"label.back": "戻る",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "コピーしました!",
"message.delete-warning": "関連するすべてのデータも削除されます。",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "問題が発生しました。",
"message.get-share-url": "共有リンクを取得",
"message.get-tracking-code": "トラッキングコードを取得",
@ -103,15 +103,10 @@
"metrics.operating-systems": "OS",
"metrics.page-views": "閲覧数",
"metrics.pages": "ページ",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "リファラー",
"metrics.screens": "Screens",
"metrics.unique-visitors": "ユニーク訪問者数",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "閲覧数",
"metrics.visitors": "訪問者数"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "웹사이트 추가",
"label.administrator": "관리자",
"label.all": "전체",
"label.all-events": "모든 이벤트",
"label.all-time": "All time",
"label.all-websites": "모든 웹사이트",
"label.back": "뒤로",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "복사했습니다!",
"message.delete-warning": "관련된 모든 데이터도 삭제됩니다.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "오류가 발생하였습니다.",
"message.get-share-url": "공유 URL 가져오기",
"message.get-tracking-code": "추적 코드 가져오기",
@ -103,15 +103,10 @@
"metrics.operating-systems": "운영체제",
"metrics.page-views": "페이지 뷰(PV)",
"metrics.pages": "페이지",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "리퍼러",
"metrics.screens": "Screens",
"metrics.unique-visitors": "순방문자(UV)",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "조회수",
"metrics.visitors": "방문객"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Pridėti svetainę",
"label.administrator": "Administratorius",
"label.all": "Visi",
"label.all-events": "Visi įvykiai",
"label.all-time": "Visas laikotarpis",
"label.all-websites": "Visos svetainės",
"label.back": "Atgal",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are esate tikri, jog norite atstatyti svetainės {target} statistikos duomenis?",
"message.copied": "Nukopijuota!",
"message.delete-warning": "Visi susiję duomenys taip pat bus ištrinti.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Kažkas įvyko ne taip.",
"message.get-share-url": "Gauti bendrinimo nuorodą",
"message.get-tracking-code": "Gauti sekimo kodą",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operacinės sistemos",
"metrics.page-views": "Puslapių peržiūros",
"metrics.pages": "Puslapiai",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referrers",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Unikalūs lankytojai",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Peržiūros",
"metrics.visitors": "Lankytojai"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Веб нэмэх",
"label.administrator": "Админ",
"label.all": "Бүх",
"label.all-events": "Бүх үйл явдал",
"label.all-time": "Бүх цаг үеийн",
"label.all-websites": "Бүх вебүүд",
"label.back": "Буцах",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Хуулсан!",
"message.delete-warning": "Үүнтэй холбоотой бүх өгөгдөл устах болно.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ямар нэг зүйл буруу боллоо.",
"message.get-share-url": "Хуваалцах холбоос авах",
"message.get-tracking-code": "Мөрдөх код авах",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Үйлдлийн систем",
"metrics.page-views": "Хуудас үзсэн",
"metrics.pages": "Хуудас",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Чиглүүлэгч",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Зочин",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Үзсэн",
"metrics.visitors": "Зочин"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Tambah laman web",
"label.administrator": "Pentadbir",
"label.all": "Semua",
"label.all-events": "Semua peristiwa",
"label.all-time": "All time",
"label.all-websites": "Semua laman web",
"label.back": "Kembali",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Disalin!",
"message.delete-warning": "Semua data yang berkaitan juga akan dihapuskan.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ada yang tidak kena.",
"message.get-share-url": "Dapatkan URL berkongsi",
"message.get-tracking-code": "Dapatkan kod penjejakan",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistem operasi",
"metrics.page-views": "Paparan halaman",
"metrics.pages": "Halaman",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Perujuk",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Pelawat unik",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Lawatan",
"metrics.visitors": "Pelawat"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Legg til nettsted",
"label.administrator": "Administrator",
"label.all": "Alle",
"label.all-events": "Alle hendelser",
"label.all-time": "Noensinne",
"label.all-websites": "Alle nettsteder",
"label.back": "Tilbake",
@ -68,6 +67,7 @@
"message.confirm-reset": "Er du sikker på at du vil nullstille {target}'s statistikk?",
"message.copied": "Kopiert!",
"message.delete-warning": "Alle tilknyttede data slettes også.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Noe gikk galt.",
"message.get-share-url": "Få delings-URL",
"message.get-tracking-code": "Få sporingskode",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operativsystemer",
"metrics.page-views": "Sidevisninger",
"metrics.pages": "Sider",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referanser",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Unike besøkende",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visninger",
"metrics.visitors": "Besøkende"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Website toevoegen",
"label.administrator": "Administrator",
"label.all": "Alles",
"label.all-events": "Alle gebeurtenissen",
"label.all-time": "Onbeperkt",
"label.all-websites": "Alle websites",
"label.back": "Terug",
@ -68,6 +67,7 @@
"message.confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?",
"message.copied": "Gekopiëerd!",
"message.delete-warning": "Alle verwante gegezens zullen ook verwijderd worden.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Er is iets misgegaan.",
"message.get-share-url": "Openbare URL",
"message.get-tracking-code": "Tracking code",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Besturingssystemen",
"metrics.page-views": "Paginaweergaven",
"metrics.pages": "Pagina's",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Verwijzers",
"metrics.screens": "Schermen",
"metrics.unique-visitors": "Unieke bezoekers",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Weergaven",
"metrics.visitors": "Bezoekers"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Dodaj witrynę",
"label.administrator": "Administrator",
"label.all": "Wszystkie",
"label.all-events": "Wszystkie wydarzenia",
"label.all-time": "Cały czas",
"label.all-websites": "Wszystkie witryny",
"label.back": "Powrót",
@ -68,6 +67,7 @@
"message.confirm-reset": "Czy na pewno chcesz zresetować statystyki {target}?",
"message.copied": "Skopiowano!",
"message.delete-warning": "Wszystkie powiązane dane również zostaną usunięte.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Coś poszło nie tak.",
"message.get-share-url": "Uzyskaj adres URL udostępniania",
"message.get-tracking-code": "Pobierz kod śledzenia",
@ -103,15 +103,10 @@
"metrics.operating-systems": "System operacyjny",
"metrics.page-views": "Wyświetlenia strony",
"metrics.pages": "Strony",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Źródła odsyłające",
"metrics.screens": "Ekrany",
"metrics.unique-visitors": "Unikalni odwiedzający",
"metrics.utm": "Kampanie UTM",
"metrics.utm_campaign": "Kampania",
"metrics.utm_content": "Treść",
"metrics.utm_medium": "Medium",
"metrics.utm_source": "Źródło",
"metrics.utm_term": "Słowa kluczowe",
"metrics.views": "Wyświetlenia",
"metrics.visitors": "Odwiedzający"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Adicionar site",
"label.administrator": "Administrador",
"label.all": "Todos",
"label.all-events": "Todos os eventos",
"label.all-time": "Todo o período",
"label.all-websites": "Todos os sites",
"label.back": "Voltar",
@ -68,6 +67,7 @@
"message.confirm-reset": "Você tem certeza que deseja redefinir as estatísticas de {target}?",
"message.copied": "Copiado!",
"message.delete-warning": "Todos os dados associados também serão eliminados.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ocorreu um erro.",
"message.get-share-url": "Obter link de compartilhamento",
"message.get-tracking-code": "Obter código de rastreamento",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operacionais",
"metrics.page-views": "Visualizações de página",
"metrics.pages": "Páginas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referências",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizações",
"metrics.visitors": "Visitantes"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Adicionar website",
"label.administrator": "Administrador",
"label.all": "Todos",
"label.all-events": "Todos os eventos",
"label.all-time": "Todo o tempo",
"label.all-websites": "Todos os websites",
"label.back": "Voltar",
@ -28,7 +27,7 @@
"label.enable-share-url": "Ativar link de partilha",
"label.invalid": "Inválido",
"label.invalid-domain": "Domínio inválido",
"label.language": "Language",
"label.language": "Língua",
"label.last-days": "Últimos {x} dias",
"label.last-hours": "Últimas {x} horas",
"label.logged-in-as": "Sessão iniciada como {username}",
@ -52,7 +51,7 @@
"label.settings": "Definições",
"label.share-url": "Partilhar link",
"label.single-day": "Dia único",
"label.theme": "Theme",
"label.theme": "Tema",
"label.this-month": "Este mês",
"label.this-week": "Esta semana",
"label.this-year": "Este ano",
@ -68,6 +67,7 @@
"message.confirm-reset": "Tem a certeza que pretende restaurar as estatísticas de {target}?",
"message.copied": "Copiado!",
"message.delete-warning": "Todos os dados associados também serão eliminados.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ocorreu um erro.",
"message.get-share-url": "Obter link de partilha",
"message.get-tracking-code": "Obter código de rastreamento",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sistemas operativos",
"metrics.page-views": "Visualizações da página",
"metrics.pages": "Páginas",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Referenciadores",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizações",
"metrics.visitors": "Visitantes"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Adăugare site web",
"label.administrator": "Administrator",
"label.all": "Toate",
"label.all-events": "Toate evenimentele",
"label.all-time": "All time",
"label.all-websites": "Toate site-urile web",
"label.back": "Înapoi",
@ -68,6 +67,7 @@
"message.confirm-reset": "Sunteți sigur că doriți să resetați statisticile pentru {target}?",
"message.copied": "Copiat!",
"message.delete-warning": "Toate datele asociate vor fi șterse, de asemenea.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Ceva n-a mers bine.",
"message.get-share-url": "Obține adresa URL de partajare",
"message.get-tracking-code": "Obține codul de urmărire",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Sisteme de operare",
"metrics.page-views": "Vizualizări de pagină",
"metrics.pages": "Pagini",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Site-uri de proveniență",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Vizitatori unici",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vizualizări",
"metrics.visitors": "Vizitatori"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Добавить сайт",
"label.administrator": "Администратор",
"label.all": "Все",
"label.all-events": "Все события",
"label.all-time": "Все время",
"label.all-websites": "Все сайты",
"label.back": "Назад",
@ -68,6 +67,7 @@
"message.confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?",
"message.copied": "Скопировано!",
"message.delete-warning": "Все связанные данные будут также удалены.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Что-то пошло не так.",
"message.get-share-url": "Получить публичную ссылку",
"message.get-tracking-code": "Получить код отслеживания",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Операционные системы",
"metrics.page-views": "Просмотры страниц",
"metrics.pages": "Страницы",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Источники",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Уникальные посетители",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Просмотры",
"metrics.visitors": "Посетители"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Pridať web",
"label.administrator": "Administrátor",
"label.all": "Všetko",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "Všetky weby",
"label.back": "Späť",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Skopírované!",
"message.delete-warning": "Všetky príbuzné data budu tiež zmazané.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Niečo sa pokazilo.",
"message.get-share-url": "Získať zdielané URL",
"message.get-tracking-code": "Získať tracking kód",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operačný systém",
"metrics.page-views": "Zobrazenie stánok",
"metrics.pages": "Stránky",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Odkazy",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Jedinečné návštevy",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Zobrazení",
"metrics.visitors": "Návštevy"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Dodaj spletno mesto",
"label.administrator": "Administrator",
"label.all": "Vse",
"label.all-events": "Vsi dogodki",
"label.all-time": "All time",
"label.all-websites": "Vsa spletna mesta",
"label.back": "Nazaj",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Kopirano!",
"message.delete-warning": "Izbrisani bodo tudi vsi povezani podatki.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Prišlo je do napake.",
"message.get-share-url": "Pridobi URL za skupno rabo",
"message.get-tracking-code": "Pridobi kodo za sledenje",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operacijski sistemi",
"metrics.page-views": "Ogledi strani",
"metrics.pages": "Strani",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Viri",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Unikatni obiskovalci",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Ogledi",
"metrics.visitors": "Obiskovalci"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Lägg till webbsajt",
"label.administrator": "Administratör",
"label.all": "Alla",
"label.all-events": "Alla händelser",
"label.all-time": "Sedan början",
"label.all-websites": "Alla sajter",
"label.back": "Tillbaka",
@ -68,6 +67,7 @@
"message.confirm-reset": "Är du säker på att du vill återställa statistiken för {target}?",
"message.copied": "Kopierad!",
"message.delete-warning": "All tillhörande data kommer också raderas.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Något gick fel.",
"message.get-share-url": "Visa delnings-URL",
"message.get-tracking-code": "Visa spårningskod",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Operativsystem",
"metrics.page-views": "Sidvisningar",
"metrics.pages": "Sidor",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Hänvisare",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Unika besökare",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visningar",
"metrics.visitors": "Besökare"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "வலைத்தளத்தைச் சேர்க்க",
"label.administrator": "நிர்வாகியைச் சேர்க்க",
"label.all": "எல்லாம்",
"label.all-events": "அனைத்து நிகழ்வுகளும்",
"label.all-time": "All time",
"label.all-websites": "அனைத்து வலைத்தளங்களும்",
"label.back": "பின்னால்",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "நகலெடுக்கப்பட்டது!",
"message.delete-warning": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "ஏதோ தவறு நடந்துவிட்டது.",
"message.get-share-url": "கள முகவரியை ஐப் பெறுக",
"message.get-tracking-code": "கண்காணிப்பு குறியீட்டைப் பெறுக",
@ -103,15 +103,10 @@
"metrics.operating-systems": "இயக்க முறைமைகள்",
"metrics.page-views": "பக்க காட்சிகள்",
"metrics.pages": "பக்கங்கள்",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "குறிப்பிடுவோர்",
"metrics.screens": "Screens",
"metrics.unique-visitors": "தனிப்பட்ட பார்வையாளர்கள்",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "பார்வைகள்",
"metrics.visitors": "பார்வையாளர்கள்"
}

112
lang/th-TH.json Normal file
View File

@ -0,0 +1,112 @@
{
"label.accounts": "บัญชี",
"label.add-account": "เพิ่มบัญชี",
"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": "เปิดใช้งานการแชร์ลิงก์",
"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": "Log แบบเรียลไทม์",
"label.refresh": "รีเฟรช",
"label.required": "ต้องการ",
"label.reset": "รีเซต",
"label.reset-website": "รีเซตข้อมูลสถิติ",
"label.save": "บันทึก",
"label.settings": "ตั้งค่า",
"label.share-url": "แชร์ลิงก์",
"label.single-day": "วันที่",
"label.theme": "ธีม",
"label.this-month": "เดือนปัจจุบัน",
"label.this-week": "สัปดาห์ปัจจุบัน",
"label.this-year": "ปีปัจจุบัน",
"label.timezone": "เขตเวลา",
"label.today": "วันนี้",
"label.tracking-code": "โค้ดสำหรับใช้ติดตาม",
"label.unknown": "ไม่รู้จัก",
"label.username": "ชื่อผู้ใช้",
"label.view-details": "แสดงรายละเอียด",
"label.websites": "เว็บไซต์",
"message.active-users": "มีผู้ใช้งาน {x} {x, plural, one {คนในขณะนี้} other {คนในขณะนี้}}",
"message.confirm-delete": "คุณแน่ใจหรือไม่ว่าต้องการลบ {target} ?",
"message.confirm-reset": "คุณแน่ใจหรือไม่ว่าต้องการรีเซตข้อมูลสถิติของ {target} ?",
"message.copied": "คัดลอกแล้ว!",
"message.delete-warning": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "เกิดข้อผิดพลาด.",
"message.get-share-url": "รับลิงก์สำหรับแชร์",
"message.get-tracking-code": "รับโค้ดสำหรับใช้ติดตาม",
"message.go-to-settings": "ไปที่การตั้งค่า",
"message.incorrect-username-password": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง.",
"message.log.visitor": "ผู้เข้าชมจาก {country} กำลังใช้งานผ่าน {browser} บน {os} {device}",
"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}.",
"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": "Query parameters",
"metrics.referrers": "แหล่งที่มา",
"metrics.screens": "ขนาดหน้าจอ",
"metrics.unique-visitors": "ผู้เข้าชม",
"metrics.views": "การเข้าชม",
"metrics.visitors": "ผู้เข้าชม"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Web sitesi ekle",
"label.administrator": "Yönetici",
"label.all": "Tümü",
"label.all-events": "All events",
"label.all-time": "All time",
"label.all-websites": "Tüm web siteleri",
"label.back": "Geri",
@ -68,6 +67,7 @@
"message.confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"message.copied": "Panoya kopyalandı!",
"message.delete-warning": "İlişkili tüm veriler de silinecektir.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Bir şeyler ters gitti!",
"message.get-share-url": "Paylaşım adresini al",
"message.get-tracking-code": "İzleme kodunu al",
@ -103,15 +103,10 @@
"metrics.operating-systems": "İşletim sistemi",
"metrics.page-views": "Sayfa görünümü",
"metrics.pages": "Sayfalar",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Yönlendirenler",
"metrics.screens": "Ekranlar",
"metrics.unique-visitors": "Tekil kullanıcı",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Görüntüleme",
"metrics.visitors": "Ziyaretçi"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Додати сайт",
"label.administrator": "Адміністратор",
"label.all": "Всі",
"label.all-events": "Всі події",
"label.all-time": "Весь час",
"label.all-websites": "Всі сайти",
"label.back": "Назад",
@ -68,6 +67,7 @@
"message.confirm-reset": "Ви впевнені, що бажаєте скинути статистику для {target}?",
"message.copied": "Скопійовано!",
"message.delete-warning": "Усі пов'язані дані будуть видалені також.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Щось пішло не так.",
"message.get-share-url": "Отримати публічне посилання",
"message.get-tracking-code": "Отримати код для відслідковування",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Операційні системи",
"metrics.page-views": "Перегляди сторінок",
"metrics.pages": "Сторінки",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Джерела",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Унікальні відвідувачі",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Перегляди",
"metrics.visitors": "Відвідувачі"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "ویب سائٹ کا اضافہ کریں",
"label.administrator": "منتظم",
"label.all": "تمام",
"label.all-events": "تمام واقعات",
"label.all-time": "تمام وقت",
"label.all-websites": "تمام ویب سائٹس",
"label.back": "پیچھے",
@ -68,6 +67,7 @@
"message.confirm-reset": "کیا آپ واقعی {target} کے اعدادوشمار کو دوبارہ ترتیب دینا چاہتے ہیں؟",
"message.copied": "کاپی کیا گیا!",
"message.delete-warning": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "کچھ غلط ہو گیا.",
"message.get-share-url": "شیئر URL حاصل کریں",
"message.get-tracking-code": "ٹریکنگ کوڈ حاصل کریں",
@ -103,15 +103,10 @@
"metrics.operating-systems": "آپریٹنگ سسٹمز",
"metrics.page-views": "صفحہ کے نظارے",
"metrics.pages": "صفحات",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "بھیجنے والے",
"metrics.screens": "Screens",
"metrics.unique-visitors": "منفرد زائرین",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "مناظر",
"metrics.visitors": "زائرین"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "Thêm website",
"label.administrator": "Quản trị",
"label.all": "Tất cả",
"label.all-events": "Tất cả sự kiện",
"label.all-time": "Toàn thời gian",
"label.all-websites": "Tất cả website",
"label.back": "Quay về",
@ -68,6 +67,7 @@
"message.confirm-reset": "Bạn có chắc chắn muốn tái thiết lập thống kê {target}?",
"message.copied": "Đã sao chép!",
"message.delete-warning": "Tất cả các dữ liệu liên quan cũng sẽ bị xoá.",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "Đã xảy ra lỗi.",
"message.get-share-url": "Lấy URL chia sẻ",
"message.get-tracking-code": "Lấy mã theo dõi",
@ -103,15 +103,10 @@
"metrics.operating-systems": "Hệ điều hành",
"metrics.page-views": "Lượt xem",
"metrics.pages": "Trang",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "Liên kết giới thiệu",
"metrics.screens": "Screens",
"metrics.unique-visitors": "Khách truy cập một lần",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Xem",
"metrics.visitors": "Khách"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "添加网站",
"label.administrator": "管理员",
"label.all": "所有",
"label.all-events": "所有事件",
"label.all-time": "所有时间段",
"label.all-websites": "全部网站",
"label.back": "返回",
@ -68,6 +67,7 @@
"message.confirm-reset": "您确定要重置 {target} 的数据吗?",
"message.copied": "复制成功!",
"message.delete-warning": "所有相关数据将会被删除。",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "出现错误。",
"message.get-share-url": "获取共享链接",
"message.get-tracking-code": "获取跟踪代码",
@ -103,15 +103,10 @@
"metrics.operating-systems": "操作系统",
"metrics.page-views": "页面浏览量",
"metrics.pages": "网页",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "来源域名",
"metrics.screens": "屏幕尺寸",
"metrics.unique-visitors": "独立访客",
"metrics.utm": "流量渠道标记UTM",
"metrics.utm_campaign": "流量标识",
"metrics.utm_content": "搜索关键字",
"metrics.utm_medium": "流量来源类型",
"metrics.utm_source": "流量来源",
"metrics.utm_term": "流量搜索关键字",
"metrics.views": "浏览量",
"metrics.visitors": "访客"
}

View File

@ -4,7 +4,6 @@
"label.add-website": "增加網站",
"label.administrator": "管理員",
"label.all": "所有",
"label.all-events": "所有事件",
"label.all-time": "所有時間段",
"label.all-websites": "全部網站",
"label.back": "返回",
@ -37,8 +36,8 @@
"label.more": "更多",
"label.name": "名字",
"label.new-password": "新密碼",
"label.none": "None",
"label.owner": "Owner",
"label.none": "",
"label.owner": "擁有者",
"label.password": "密碼",
"label.passwords-dont-match": "密碼不一致",
"label.profile": "個人資料",
@ -52,7 +51,7 @@
"label.settings": "設置",
"label.share-url": "分享連結",
"label.single-day": "單日",
"label.theme": "Theme",
"label.theme": "主題",
"label.this-month": "本月",
"label.this-week": "本週",
"label.this-year": "今年",
@ -68,6 +67,7 @@
"message.confirm-reset": "您確定要重置 {target} 的數據嗎?",
"message.copied": "複製成功!",
"message.delete-warning": "所有相關數據將會被刪除。",
"message.edit-dashboard": "Edit dashboard",
"message.failure": "出現錯誤。",
"message.get-share-url": "獲得分享連結",
"message.get-tracking-code": "獲得追蹤代碼",
@ -82,7 +82,7 @@
"message.reset-warning": "本網站的所有統計數據將被刪除,但您的跟蹤代碼將保持不變。",
"message.save-success": "成功保存。",
"message.share-url": "這是 {target} 的分享連結。",
"message.toggle-charts": "Toggle charts",
"message.toggle-charts": "切換圖表",
"message.track-stats": "將以下代碼放入被設定網站的 {head} 部分來收集 {target} 的資料。",
"message.type-delete": "在下方空格輸入 {delete} 確認删除",
"message.type-reset": "在下方空格輸入 {reset} 確認删除",
@ -99,19 +99,14 @@
"metrics.events": "行為類別",
"metrics.filter.combined": "總和",
"metrics.filter.raw": "原始",
"metrics.languages": "Languages",
"metrics.operating-systems": "操作系",
"metrics.languages": "語言",
"metrics.operating-systems": "操作系",
"metrics.page-views": "網頁流量",
"metrics.pages": "網頁",
"metrics.query-parameters": "Query parameters",
"metrics.referrers": "指入域名",
"metrics.screens": "Screens",
"metrics.screens": "屏幕尺寸",
"metrics.unique-visitors": "獨立訪客",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "頁面流量",
"metrics.visitors": "獨立訪客"
}

View File

@ -9,3 +9,10 @@ export function chunk(arr, size) {
return chunks;
}
export function sortArrayByMap(arr, map = [], key) {
if (!arr) return [];
if (map.length === 0) return arr;
return map.map(id => arr.find(item => item[key] === id));
}

View File

@ -1,3 +1,4 @@
export const CURRENT_VERSION = process.env.currentVersion;
export const AUTH_TOKEN = 'umami.auth';
export const LOCALE_CONFIG = 'umami.locale';
export const TIMEZONE_CONFIG = 'umami.timezone';
@ -9,6 +10,7 @@ export const SHARE_TOKEN_HEADER = 'x-umami-share-token';
export const HOMEPAGE_URL = 'https://umami.is';
export const REPO_URL = 'https://github.com/umami-software/umami';
export const UPDATES_URL = 'https://api.umami.is/v1/updates';
export const TELEMETRY_PIXEL = 'https://i.umami.is/a.png';
export const DEFAULT_LOCALE = 'en-US';
export const DEFAULT_THEME = 'light';

View File

@ -168,7 +168,6 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
if (table === 'pageview' || table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter));
console.log(params);
}
break;
@ -182,7 +181,7 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
}
break;
case 'event_type':
case 'event_name':
if (table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter));
@ -203,6 +202,11 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
params.push(`%://${filter}/%`);
}
break;
case 'query':
if (table === 'pageview') {
arr.push(`and ${table}.url like '%?%'`);
}
}
return arr;
@ -212,17 +216,20 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
}
export function parseFilters(table, column, filters = {}, params = [], sessionKey = 'session_id') {
const { domain, url, event_url, referrer, os, browser, device, country, event_type } = filters;
const { domain, url, event_url, referrer, os, browser, device, country, event_name, query } =
filters;
const pageviewFilters = { domain, url, referrer };
console.log({ table, column, filters, params });
const pageviewFilters = { domain, url, referrer, query };
const sessionFilters = { os, browser, device, country };
const eventFilters = { url: event_url, event_type };
const eventFilters = { url: event_url, event_name };
return {
pageviewFilters,
sessionFilters,
eventFilters,
event: { event_type },
event: { event_name },
joinSession:
os || browser || device || country
? `inner join session on ${table}.${sessionKey} = session.${sessionKey}`
@ -277,14 +284,22 @@ export async function rawQueryClickhouse(query, params = [], debug = false) {
return clickhouse.query(formattedQuery).toPromise();
}
export async function findUnique(data) {
if (data.length > 1) {
throw `${data.length} records found when expecting 1.`;
}
return data[0] ?? null;
}
export async function runAnalyticsQuery(queries) {
const db = getAnalyticsDatabase();
if (db === POSTGRESQL || db === MYSQL) {
return queries[`${RELATIONAL}`]();
return queries[RELATIONAL]();
}
if (db === CLICKHOUSE) {
return queries[`${CLICKHOUSE}`]();
return queries[CLICKHOUSE]();
}
}

View File

@ -68,18 +68,37 @@ export const refFilter = data => {
return Object.keys(map).map(key => ({ x: key, y: map[key], w: links[key] }));
};
export const eventTypeFilter = (data, types) => {
if (!types || types.length === 0) {
return data;
}
return data.filter(({ x }) => {
const [event] = x.split('\t');
return types.some(type => type === event);
});
};
export const percentFilter = data => {
const total = data.reduce((n, { y }) => n + y, 0);
return data.map(({ x, y, ...props }) => ({ x, y, z: total ? (y / total) * 100 : 0, ...props }));
};
export const paramFilter = data => {
const map = data.reduce((obj, { x, y }) => {
try {
const searchParams = new URLSearchParams(x.split('?')[1]);
for (const [key, value] of searchParams) {
if (!obj[key]) {
obj[key] = { [value]: y };
} else if (!obj[key][value]) {
obj[key][value] = y;
} else {
obj[key][value] += y;
}
}
} catch {
// Ignore
}
return obj;
}, {});
const d = Object.keys(map).flatMap(key =>
Object.keys(map[key]).map(n => ({ x: `${key}=${n}`, p: key, v: n, y: map[key][n] })),
);
console.log({ map, d });
return d;
};

View File

@ -1,5 +1,6 @@
import {
arSA,
bn,
cs,
sk,
da,
@ -30,6 +31,7 @@ import {
sl,
sv,
ta,
th,
tr,
uk,
zhCN,
@ -41,6 +43,7 @@ import {
export const languages = {
'ar-SA': { label: 'العربية', dateLocale: arSA, dir: 'rtl' },
'bn-BD': { label: 'বাংলা', dateLocale: bn },
'zh-CN': { label: '中文', dateLocale: zhCN },
'zh-TW': { label: '中文(繁體)', dateLocale: zhTW },
'ca-ES': { label: 'Català', dateLocale: ca },
@ -77,6 +80,7 @@ export const languages = {
'fi-FI': { label: 'Suomi', dateLocale: fi },
'sv-SE': { label: 'Svenska', dateLocale: sv },
'ta-IN': { label: 'தமிழ்', dateLocale: ta },
'th-TH': { label: 'ภาษาไทย', dateLocale: th },
'tr-TR': { label: 'Türkçe', dateLocale: tr },
'uk-UA': { label: 'українська', dateLocale: uk },
'ur-PK': { label: 'Urdu (Pakistan)', dateLocale: uk, dir: 'rtl' },

View File

@ -68,7 +68,7 @@ export async function getCountry(req, ip) {
// Database lookup
if (!lookup) {
lookup = await maxmind.open(path.resolve('./public/geo/GeoLite2-Country.mmdb'));
lookup = await maxmind.open(path.resolve('node_modules/.geo/GeoLite2-Country.mmdb'));
}
const result = lookup.get(ip);

View File

@ -37,8 +37,6 @@ export async function getSession(req) {
let session = await getSessionByUuid(session_uuid);
session = Array.isArray(session) && session[0] ? session[0] : session;
if (!session) {
try {
session = await createSession(website_id, {

View File

@ -61,10 +61,15 @@ export const setItem = (key, data, session) => {
}
};
export const getItem = (key, session) =>
typeof window !== 'undefined'
? JSON.parse((session ? sessionStorage : localStorage).getItem(key) || null)
: null;
export const getItem = (key, session) => {
if (typeof window !== 'undefined') {
const value = (session ? sessionStorage : localStorage).getItem(key);
if (value !== 'undefined') {
return JSON.parse(value);
}
}
};
export const removeItem = (key, session) => {
if (typeof window !== 'undefined') {

View File

@ -33,14 +33,6 @@ function customScriptName(req) {
}
}
function forceSSL(req, res) {
if (process.env.FORCE_SSL && req.nextUrl.protocol === 'http:') {
res.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
}
return res;
}
export default function middleware(req) {
const fns = [customCollectEndpoint, customScriptName];
@ -51,5 +43,5 @@ export default function middleware(req) {
}
}
return forceSSL(req, NextResponse.next());
return NextResponse.next();
}

View File

@ -1,12 +1,41 @@
require('dotenv').config();
const pkg = require('./package.json');
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';
`;
const headers = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'Content-Security-Policy',
value: contentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(),
},
];
if (process.env.FORCE_SSL) {
headers.push({
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
});
}
module.exports = {
env: {
currentVersion: pkg.version,
loginDisabled: process.env.DISABLE_LOGIN,
updatesDisabled: process.env.DISABLE_UPDATES,
telemetryDisabled: process.env.DISABLE_TELEMETRY,
isProduction: process.env.NODE_ENV === 'production',
},
basePath: process.env.BASE_PATH,
output: 'standalone',
@ -25,13 +54,16 @@ module.exports = {
async headers() {
return [
{
source: `/(.*\\.js)`,
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=2592000', // 30 days
},
],
source: '/:path*',
headers,
},
];
},
async rewrites() {
return [
{
source: '/telemetry.js',
destination: '/api/scripts/telemetry',
},
];
},

View File

@ -1,6 +1,6 @@
{
"name": "umami",
"version": "1.36.1",
"version": "1.37.0",
"description": "A simple, fast, privacy-focused alternative to Google Analytics.",
"author": "Mike Cao <mike@mikecao.com>",
"license": "MIT",
@ -13,17 +13,18 @@
"dev": "next dev",
"build": "npm-run-all build-tracker build-geo build-db build-app",
"start": "npm-run-all check-db start-next",
"start-docker": "npm-run-all check-db start-server",
"start-docker": "npm-run-all check-db update-tracker start-server",
"start-env": "node scripts/start-env.js",
"start-server": "node server.js",
"start-next": "next start",
"build-app": "next build",
"build-tracker": "rollup -c rollup.tracker.config.js",
"build-db": "npm-run-all copy-db-files build-db-client",
"build-lang": "npm-run-all format-lang compile-lang",
"build-lang": "npm-run-all format-lang compile-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",
"copy-db-files": "node scripts/copy-db-files.js",
@ -55,7 +56,7 @@
},
"dependencies": {
"@fontsource/inter": "4.5.7",
"@prisma/client": "4.1.0",
"@prisma/client": "4.1.1",
"bcryptjs": "^2.4.3",
"chalk": "^4.1.1",
"chart.js": "^2.9.4",
@ -80,11 +81,12 @@
"jose": "2.0.5",
"maxmind": "^4.3.6",
"moment-timezone": "^0.5.33",
"next": "^12.2.0",
"next": "^12.2.4",
"node-fetch": "^3.2.8",
"npm-run-all": "^4.1.5",
"prop-types": "^15.7.2",
"react": "^17.0.0",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "^17.0.0",
"react-intl": "^5.24.7",
"react-simple-maps": "^2.3.0",
@ -106,7 +108,7 @@
"@svgr/webpack": "^6.2.1",
"cross-env": "^7.0.3",
"eslint": "^7.32.0",
"eslint-config-next": "^12.2.0",
"eslint-config-next": "^12.2.4",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"extract-react-intl-messages": "^4.1.1",
@ -118,7 +120,7 @@
"postcss-preset-env": "7.4.3",
"postcss-rtlcss": "^3.6.1",
"prettier": "^2.6.2",
"prisma": "4.1.0",
"prisma": "4.1.1",
"prompts": "2.4.2",
"rollup": "^2.70.1",
"rollup-plugin-terser": "^7.0.2",
@ -127,5 +129,8 @@
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recommended": "^7.0.0",
"tar": "^6.1.2"
}
},
"cacheDirectories": [
".next/cache"
]
}

View File

@ -1,4 +1,3 @@
import React from 'react';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { IntlProvider } from 'react-intl';

View File

@ -65,7 +65,7 @@ export default async (req, res) => {
const { type, payload } = getJsonBody(req);
let { url, referrer, event_type, event_value } = payload;
let { url, referrer, event_name, event_data } = payload;
if (process.env.REMOVE_TRAILING_SLASH) {
url = removeTrailingSlash(url);
@ -74,7 +74,7 @@ export default async (req, res) => {
if (type === 'pageview') {
await savePageView(website_id, { session_id, session_uuid, url, referrer });
} else if (type === 'event') {
await saveEvent(website_id, { session_id, session_uuid, url, event_type, event_value });
await saveEvent(website_id, { session_id, session_uuid, url, event_name, event_data });
} else {
return badRequest(res);
}

14
pages/api/config.js Normal file
View File

@ -0,0 +1,14 @@
import { ok, methodNotAllowed } from 'lib/response';
export default async (req, res) => {
if (req.method === 'GET') {
return ok(res, {
basePath: process.env.BASE_PATH || '',
trackerScriptName: process.env.TRACKER_SCRIPT_NAME,
updatesDisabled: !!process.env.DISABLE_UPDATES,
telemetryDisabled: !!process.env.DISABLE_TELEMETRY,
});
}
return methodNotAllowed(res);
};

View File

@ -0,0 +1,18 @@
import { CURRENT_VERSION, TELEMETRY_PIXEL } from 'lib/constants';
export default function handler(req, res) {
res.setHeader('content-type', 'text/javascript');
if (process.env.DISABLE_TELEMETRY) {
return res.send('/* telemetry disabled */');
}
const script = `
(()=>{const i=document.createElement('img');
i.setAttribute('src','${TELEMETRY_PIXEL}?v=${CURRENT_VERSION}');
i.setAttribute('style','width:0;height:0;position:absolute;pointer-events:none;');
document.body.appendChild(i);})();
`;
return res.send(script.replace(/\s\s+/g, ''));
}

View File

@ -14,7 +14,7 @@ export default async (req, res) => {
return unauthorized(res);
}
const { id, start_at, end_at, unit, tz, url, event_type } = req.query;
const { id, start_at, end_at, unit, tz, url, event_name } = req.query;
if (!moment.tz.zone(tz) || !unitTypes.includes(unit)) {
return badRequest(res);
@ -26,7 +26,7 @@ export default async (req, res) => {
const events = await getEventMetrics(websiteId, startDate, endDate, tz, unit, {
url,
event_type,
event_name,
});
return ok(res, events);

View File

@ -1,12 +1,11 @@
import { getPageviewMetrics, getSessionMetrics, getWebsiteById, getPageviewParams } from 'queries';
import { getPageviewMetrics, getSessionMetrics, getWebsiteById } from 'queries';
import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response';
import { allowQuery } from 'lib/auth';
import { useCors } from 'lib/middleware';
import { FILTER_IGNORED } from 'lib/constants';
const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language'];
const pageviewColumns = ['url', 'referrer'];
const paramTypes = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'ref'];
const pageviewColumns = ['url', 'referrer', 'query'];
function getTable(type) {
if (type === 'event') {
@ -17,12 +16,19 @@ function getTable(type) {
return 'session';
}
return 'pageview';
if (pageviewColumns.includes(type)) {
return 'pageview';
}
throw new Error('Invalid type');
}
function getColumn(type) {
if (type === 'event') {
return `concat(event_type, '\t', event_value)`;
return 'event_name';
}
if (type === 'query') {
return 'url';
}
return type;
}
@ -41,52 +47,6 @@ export default async (req, res) => {
const startDate = new Date(+start_at);
const endDate = new Date(+end_at);
if (paramTypes.includes(type)) {
const column = 'url';
const table = getTable(type);
let domain;
if (type === 'referrer') {
const website = await getWebsiteById(websiteId);
if (!website) {
return badRequest(res);
}
domain = website.domain;
}
const filters = {
domain,
url: type !== 'url' && table !== 'event' ? url : undefined,
referrer: type !== 'referrer' ? referrer : true,
os: type !== 'os' ? os : undefined,
browser: type !== 'browser' ? browser : undefined,
device: type !== 'device' ? device : undefined,
country: type !== 'country' ? country : undefined,
event_url: type !== 'url' && table === 'event' ? url : undefined,
};
let data = await getPageviewParams(
type,
websiteId,
startDate,
endDate,
column,
table,
filters,
);
let terms = {};
new Set(data.map(i => i.param)).forEach(term => (terms[term] = null));
for (let { param } of data) terms[param] += 1;
return ok(
res,
Object.keys(terms).map(i => ({ x: i, y: terms[i] })),
);
}
if (sessionColumns.includes(type)) {
let data = await getSessionMetrics(websiteId, startDate, endDate, type, {
os,
@ -116,6 +76,7 @@ export default async (req, res) => {
if (pageviewColumns.includes(type) || type === 'event') {
let domain;
if (type === 'referrer') {
const website = await getWebsiteById(websiteId);
@ -137,6 +98,7 @@ export default async (req, res) => {
device: type !== 'device' ? device : undefined,
country: type !== 'country' ? country : undefined,
event_url: type !== 'url' && table === 'event' ? url : undefined,
query: type === 'query' && table !== 'event' ? true : undefined,
};
const data = await getPageviewMetrics(websiteId, startDate, endDate, column, table, filters);

View File

@ -2,11 +2,13 @@ import React from 'react';
import Layout from 'components/layout/Layout';
import TestConsole from 'components/pages/TestConsole';
import useRequireLogin from 'hooks/useRequireLogin';
import useUser from 'hooks/useUser';
export default function TestPage() {
export default function ConsolePage({ enabled }) {
const { loading } = useRequireLogin();
const { user } = useUser();
if (loading) {
if (loading || !enabled || !user?.is_admin) {
return null;
}
@ -16,3 +18,9 @@ export default function TestPage() {
</Layout>
);
}
export async function getServerSideProps() {
return {
props: { enabled: !!process.env.ENABLE_TEST_CONSOLE },
};
}

View File

@ -2,8 +2,8 @@ import React from 'react';
import Layout from 'components/layout/Layout';
import LoginForm from 'components/forms/LoginForm';
export default function LoginPage() {
if (process.env.loginDisabled) {
export default function LoginPage({ loginDisabled }) {
if (loginDisabled) {
return null;
}
@ -13,3 +13,9 @@ export default function LoginPage() {
</Layout>
);
}
export async function getServerSideProps() {
return {
props: { loginDisabled: !!process.env.DISABLE_LOGIN },
};
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -29,12 +29,6 @@
"value": "الكل"
}
],
"label.all-events": [
{
"type": 0,
"value": "كافة الأحداث"
}
],
"label.all-time": [
{
"type": 0,
@ -477,6 +471,12 @@
"value": "كافة البيانات المرتبطة سيم حذفها ايضا."
}
],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [
{
"type": 0,
@ -767,6 +767,12 @@
"value": "الصفحات"
}
],
"metrics.query-parameters": [
{
"type": 0,
"value": "Query parameters"
}
],
"metrics.referrers": [
{
"type": 0,
@ -785,42 +791,6 @@
"value": "زائرون فريدون"
}
],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [
{
"type": 0,

View File

@ -0,0 +1,802 @@
{
"label.accounts": [
{
"type": 0,
"value": "অ্যাকাউন্ট"
}
],
"label.add-account": [
{
"type": 0,
"value": "অ্যাকাউন্ট যুক্ত করুন"
}
],
"label.add-website": [
{
"type": 0,
"value": "ওয়েবসাইট যুক্ত করুন"
}
],
"label.administrator": [
{
"type": 0,
"value": "অ্যাডমিন"
}
],
"label.all": [
{
"type": 0,
"value": "সবগুলো"
}
],
"label.all-time": [
{
"type": 0,
"value": "সব সময়"
}
],
"label.all-websites": [
{
"type": 0,
"value": "সবগুলো ওয়েবসাইট"
}
],
"label.back": [
{
"type": 0,
"value": "পেছনে"
}
],
"label.cancel": [
{
"type": 0,
"value": "বাতিল"
}
],
"label.change-password": [
{
"type": 0,
"value": "পাসওয়ার্ড পরিবর্তন করুন"
}
],
"label.confirm-password": [
{
"type": 0,
"value": "পাসওয়ার্ড নিশ্চিত করুন"
}
],
"label.copy-to-clipboard": [
{
"type": 0,
"value": "কপি করুন"
}
],
"label.current-password": [
{
"type": 0,
"value": "বর্তমান পাসওয়ার্ড"
}
],
"label.custom-range": [
{
"type": 0,
"value": "কাস্টম রেঞ্জ"
}
],
"label.dashboard": [
{
"type": 0,
"value": "ড্যাশবোর্ড"
}
],
"label.date-range": [
{
"type": 0,
"value": "তারিখের পরিসীমা"
}
],
"label.default-date-range": [
{
"type": 0,
"value": "ডিফল্ট তারিখের পরিসীমা"
}
],
"label.delete": [
{
"type": 0,
"value": "মুছে ফেলুন"
}
],
"label.delete-account": [
{
"type": 0,
"value": "অ্যাকাউন্ট মুছুন"
}
],
"label.delete-website": [
{
"type": 0,
"value": "ওয়েবসাইট মুছুন"
}
],
"label.dismiss": [
{
"type": 0,
"value": "বাতিল"
}
],
"label.domain": [
{
"type": 0,
"value": "ডোমেইন"
}
],
"label.edit": [
{
"type": 0,
"value": "সম্পাদনা করুন"
}
],
"label.edit-account": [
{
"type": 0,
"value": "অ্যাকাউন্ট সম্পাদনা করুন"
}
],
"label.edit-website": [
{
"type": 0,
"value": "ওয়েবসাইট সম্পাদনা করুন"
}
],
"label.enable-share-url": [
{
"type": 0,
"value": "শেয়ার ইউআরএল শেয়ার করুন"
}
],
"label.invalid": [
{
"type": 0,
"value": "ভুল"
}
],
"label.invalid-domain": [
{
"type": 0,
"value": "ভুল ডোমেন"
}
],
"label.language": [
{
"type": 0,
"value": "ভাষা"
}
],
"label.last-days": [
{
"type": 0,
"value": "শেষ "
},
{
"type": 1,
"value": "x"
},
{
"type": 0,
"value": " দিন"
}
],
"label.last-hours": [
{
"type": 0,
"value": "শেষ "
},
{
"type": 1,
"value": "x"
},
{
"type": 0,
"value": " ঘন্টা"
}
],
"label.logged-in-as": [
{
"type": 1,
"value": "username"
},
{
"type": 0,
"value": " অ্যাকাউন্টে লগ ইন"
}
],
"label.login": [
{
"type": 0,
"value": "লগিন"
}
],
"label.logout": [
{
"type": 0,
"value": "লগ আউট"
}
],
"label.more": [
{
"type": 0,
"value": "আরও"
}
],
"label.name": [
{
"type": 0,
"value": "নাম"
}
],
"label.new-password": [
{
"type": 0,
"value": "নতুন পাসওয়ার্ড"
}
],
"label.none": [
{
"type": 0,
"value": "কিছুই না"
}
],
"label.owner": [
{
"type": 0,
"value": "মালিক"
}
],
"label.password": [
{
"type": 0,
"value": "পাসওয়ার্ড"
}
],
"label.passwords-dont-match": [
{
"type": 0,
"value": "পাসওয়ার্ড মেলে না"
}
],
"label.profile": [
{
"type": 0,
"value": "প্রোফাইল"
}
],
"label.realtime": [
{
"type": 0,
"value": "সরাসরি"
}
],
"label.realtime-logs": [
{
"type": 0,
"value": "সরাসরি লগ"
}
],
"label.refresh": [
{
"type": 0,
"value": "রিফ্রেশ"
}
],
"label.required": [
{
"type": 0,
"value": "প্রয়োজনীয়"
}
],
"label.reset": [
{
"type": 0,
"value": "রিসেট"
}
],
"label.reset-website": [
{
"type": 0,
"value": "ওয়েবসাইট রিসেট করুন"
}
],
"label.save": [
{
"type": 0,
"value": "সংরক্ষণ"
}
],
"label.settings": [
{
"type": 0,
"value": "সেটিংস"
}
],
"label.share-url": [
{
"type": 0,
"value": "ইউআরএল শেয়ার করুন"
}
],
"label.single-day": [
{
"type": 0,
"value": "একদিন"
}
],
"label.theme": [
{
"type": 0,
"value": "থিম"
}
],
"label.this-month": [
{
"type": 0,
"value": "এই মাস"
}
],
"label.this-week": [
{
"type": 0,
"value": "এই সপ্তাহ"
}
],
"label.this-year": [
{
"type": 0,
"value": "এই বছর"
}
],
"label.timezone": [
{
"type": 0,
"value": "সময়স্থান"
}
],
"label.today": [
{
"type": 0,
"value": "আজ"
}
],
"label.tracking-code": [
{
"type": 0,
"value": "ট্র্যাকিং কোড"
}
],
"label.unknown": [
{
"type": 0,
"value": "অজানা"
}
],
"label.username": [
{
"type": 0,
"value": "ব্যবহারকারীর নাম"
}
],
"label.view-details": [
{
"type": 0,
"value": "বিস্তারিত দেখুন"
}
],
"label.websites": [
{
"type": 0,
"value": "সবগুলো ওয়েবসাইট"
}
],
"message.active-users": [
{
"type": 1,
"value": "x"
},
{
"type": 0,
"value": " বর্তমান "
},
{
"offset": 0,
"options": {
"one": {
"value": [
{
"type": 0,
"value": "visitor"
}
]
},
"other": {
"value": [
{
"type": 0,
"value": "visitors"
}
]
}
},
"pluralType": "cardinal",
"type": 6,
"value": "x"
}
],
"message.confirm-delete": [
{
"type": 0,
"value": "আপনি কি নিশ্চিত যে আপনি "
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " মুছতে চান?"
}
],
"message.confirm-reset": [
{
"type": 0,
"value": "আপনি কি নিশ্চিত যে আপনি "
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " এর পরিসংখ্যান পুনরায় সেট করতে চান?"
}
],
"message.copied": [
{
"type": 0,
"value": "কপি হয়েছে"
}
],
"message.delete-warning": [
{
"type": 0,
"value": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।"
}
],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [
{
"type": 0,
"value": "কিছু ভুল হয়েছে।"
}
],
"message.get-share-url": [
{
"type": 0,
"value": "শেয়ার ইউআরএল"
}
],
"message.get-tracking-code": [
{
"type": 0,
"value": "ট্র্যাকিং কোড পান"
}
],
"message.go-to-settings": [
{
"type": 0,
"value": "সেটিংস এ যান"
}
],
"message.incorrect-username-password": [
{
"type": 0,
"value": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।"
}
],
"message.log.visitor": [
{
"type": 1,
"value": "country"
},
{
"type": 0,
"value": " থেকে একজন ভিসিটর "
},
{
"type": 1,
"value": "ব্রাউজার"
},
{
"type": 0,
"value": ", ব্যবহার করছেন "
},
{
"type": 1,
"value": "os"
},
{
"type": 0,
"value": " "
},
{
"type": 1,
"value": "device"
},
{
"type": 0,
"value": " এর মধ্যে।"
}
],
"message.new-version-available": [
{
"type": 0,
"value": "নতুন সংস্করণ "
},
{
"type": 1,
"value": "version"
},
{
"type": 0,
"value": " পাওয়া গিয়েছে।"
}
],
"message.no-data-available": [
{
"type": 0,
"value": "কোন তথ্য নেই।"
}
],
"message.no-websites-configured": [
{
"type": 0,
"value": "কোনও ওয়েবসাইট কনফিগার করা নেই।"
}
],
"message.page-not-found": [
{
"type": 0,
"value": "পৃষ্ঠা খুঁজে পাওয়া যায়নি।"
}
],
"message.powered-by": [
{
"type": 1,
"value": "name"
},
{
"type": 0,
"value": " দ্বারা চালিত"
}
],
"message.reset-warning": [
{
"type": 0,
"value": "এই ওয়েবসাইটের সমস্ত পরিসংখ্যান মুছে ফেলা হবে, তবে আপনার ট্র্যাকিং কোডটি অক্ষত থাকবে।"
}
],
"message.save-success": [
{
"type": 0,
"value": "সংরক্ষিত হয়েছে।"
}
],
"message.share-url": [
{
"type": 0,
"value": "এটি "
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " এর জন্য প্রকাশ্যে শেয়ার করার ইউআরএল।"
}
],
"message.toggle-charts": [
{
"type": 0,
"value": "চার্ট পরিবর্তন করুন"
}
],
"message.track-stats": [
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": " এর জন্য পরিসংখ্যানগুলি ট্র্যাক করতে, আপনার ওয়েবসাইটের "
},
{
"type": 1,
"value": "head"
},
{
"type": 0,
"value": " বিভাগে নিম্নলিখিত কোডটি রাখুন।"
}
],
"message.type-delete": [
{
"type": 0,
"value": "নিশ্চিত করতে নীচের বাক্সে "
},
{
"type": 1,
"value": "delete"
},
{
"type": 0,
"value": " টাইপ করুন।"
}
],
"message.type-reset": [
{
"type": 0,
"value": "নিশ্চিত করতে নীচের বাক্সে "
},
{
"type": 1,
"value": "reset"
},
{
"type": 0,
"value": " টাইপ করুন।"
}
],
"metrics.actions": [
{
"type": 0,
"value": "অ্যাকশনস"
}
],
"metrics.average-visit-time": [
{
"type": 0,
"value": "গড় পরিদর্শনের সময়"
}
],
"metrics.bounce-rate": [
{
"type": 0,
"value": "বহিষ্কারের হার"
}
],
"metrics.browsers": [
{
"type": 0,
"value": "ব্রাউজার"
}
],
"metrics.countries": [
{
"type": 0,
"value": "দেশ"
}
],
"metrics.device.desktop": [
{
"type": 0,
"value": "ডেস্কটপ"
}
],
"metrics.device.laptop": [
{
"type": 0,
"value": "ল্যাপটপ"
}
],
"metrics.device.mobile": [
{
"type": 0,
"value": "মুঠোফোন"
}
],
"metrics.device.tablet": [
{
"type": 0,
"value": "ট্যাবলেট"
}
],
"metrics.devices": [
{
"type": 0,
"value": "ডিভাইস গুলো"
}
],
"metrics.events": [
{
"type": 0,
"value": "ঘটনা"
}
],
"metrics.filter.combined": [
{
"type": 0,
"value": "সম্মিলিত"
}
],
"metrics.filter.raw": [
{
"type": 0,
"value": "অপরিশোধিত"
}
],
"metrics.languages": [
{
"type": 0,
"value": "ভাষা"
}
],
"metrics.operating-systems": [
{
"type": 0,
"value": "অপারেটিং সিস্টেম গুলো"
}
],
"metrics.page-views": [
{
"type": 0,
"value": "পৃষ্ঠা পরিদর্শন গুলো"
}
],
"metrics.pages": [
{
"type": 0,
"value": "পৃষ্ঠাগুলি"
}
],
"metrics.query-parameters": [
{
"type": 0,
"value": "Query parameters"
}
],
"metrics.referrers": [
{
"type": 0,
"value": "রেফারার্স"
}
],
"metrics.screens": [
{
"type": 0,
"value": "স্ক্রিনগুলি"
}
],
"metrics.unique-visitors": [
{
"type": 0,
"value": "অনন্য ভিজিটর"
}
],
"metrics.views": [
{
"type": 0,
"value": "ভিউস"
}
],
"metrics.visitors": [
{
"type": 0,
"value": "পরিদর্শনার্থী"
}
]
}

View File

@ -29,12 +29,6 @@
"value": "Tots"
}
],
"label.all-events": [
{
"type": 0,
"value": "Tots els esdeveniments"
}
],
"label.all-time": [
{
"type": 0,
@ -477,6 +471,12 @@
"value": "També s'esborraran totes les dades relacionades."
}
],
"message.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
}
],
"message.failure": [
{
"type": 0,
@ -767,6 +767,12 @@
"value": "Pàgines"
}
],
"metrics.query-parameters": [
{
"type": 0,
"value": "Query parameters"
}
],
"metrics.referrers": [
{
"type": 0,
@ -785,42 +791,6 @@
"value": "Visitants únics"
}
],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [
{
"type": 0,

Some files were not shown because too many files have changed in this diff Show More