@harshankur/viewcounter 3.0.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +50 -6
- package/README.md +444 -104
- package/admin/apple-touch-icon.png +0 -0
- package/admin/assets/world-map.json +1 -0
- package/admin/css/admin.css +2568 -0
- package/admin/favicon.ico +0 -0
- package/admin/favicon.svg +9 -0
- package/admin/icon-192.png +0 -0
- package/admin/icon-512.png +0 -0
- package/admin/index.html +95 -0
- package/admin/js/api.js +146 -0
- package/admin/js/appTabs.js +100 -0
- package/admin/js/charts.js +842 -0
- package/admin/js/clamp.js +41 -0
- package/admin/js/constants.js +239 -0
- package/admin/js/dataTable.js +478 -0
- package/admin/js/dom.js +83 -0
- package/admin/js/format.js +130 -0
- package/admin/js/i18n.js +80 -0
- package/admin/js/icons.js +168 -0
- package/admin/js/listbox.js +145 -0
- package/admin/js/logs.js +318 -0
- package/admin/js/main.js +399 -0
- package/admin/js/modal.js +171 -0
- package/admin/js/overview.js +905 -0
- package/admin/js/passwordPrompt.js +75 -0
- package/admin/js/table.js +94 -0
- package/admin/js/theme.js +72 -0
- package/admin/js/toast.js +47 -0
- package/admin/js/viewDialogs.js +224 -0
- package/admin/js/views.js +751 -0
- package/admin/locales/en.json +683 -0
- package/admin/site.webmanifest +20 -0
- package/config/index.js +122 -4
- package/constants.js +334 -3
- package/db/AdminRepository.js +488 -0
- package/db/DatabaseManager.js +148 -26
- package/db/LogRepository.js +354 -0
- package/db/adminSchema.js +329 -0
- package/db/adminSessionStore.js +104 -0
- package/db/analysis.js +479 -0
- package/db/rejectionCounter.js +117 -0
- package/db/retention.js +97 -0
- package/index.js +91 -24
- package/middleware/adminAuth.js +244 -0
- package/middleware/adminValidation.js +319 -0
- package/middleware/auth.js +2 -2
- package/middleware/security.js +26 -2
- package/middleware/validation.js +50 -2
- package/package.json +20 -10
- package/routes/admin.js +546 -0
- package/routes/analytics.js +207 -19
- package/tracker/tracker.js +191 -0
- package/utils/appIdUtils.js +1 -1
- package/utils/cookieUtils.js +47 -0
- package/utils/durationUtils.js +33 -0
- package/utils/errorUtils.js +39 -1
- package/utils/geoCity.js +87 -0
- package/utils/ipUtils.js +1 -1
- package/utils/privacyUtils.js +2 -2
- package/utils/referrerParser.js +23 -5
- package/utils/secretStore.js +1 -1
- package/utils/userAgentParser.js +52 -3
- package/utils/visitorContext.js +70 -0
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
{
|
|
2
|
+
"app": {
|
|
3
|
+
"name": "viewcounter",
|
|
4
|
+
"badge": "admin",
|
|
5
|
+
"documentTitle": "ViewCounter Admin",
|
|
6
|
+
"version": "v{version}"
|
|
7
|
+
},
|
|
8
|
+
"nav": {
|
|
9
|
+
"skip": "Skip to content",
|
|
10
|
+
"logout": "Sign out",
|
|
11
|
+
"website": "Website",
|
|
12
|
+
"websiteTitle": "viewcounter's website, in a new tab"
|
|
13
|
+
},
|
|
14
|
+
"theme": {
|
|
15
|
+
"label": "Colour theme",
|
|
16
|
+
"light": "Light mode",
|
|
17
|
+
"dark": "Dark mode",
|
|
18
|
+
"auto": "System preference"
|
|
19
|
+
},
|
|
20
|
+
"login": {
|
|
21
|
+
"windowTitle": "admin@viewcounter:~",
|
|
22
|
+
"heading": "sign in",
|
|
23
|
+
"intro": "Enter the admin password configured as ADMIN_PASSWORD on this server.",
|
|
24
|
+
"password": "Password",
|
|
25
|
+
"submit": "Sign in",
|
|
26
|
+
"signedOut": "You have been signed out."
|
|
27
|
+
},
|
|
28
|
+
"session": {
|
|
29
|
+
"endedTitle": "Signed out",
|
|
30
|
+
"endedMessage": "Your session has ended. Sign in again to carry on where you left off.",
|
|
31
|
+
"confirmTitle": "Confirm it is you",
|
|
32
|
+
"confirmMessage": "Erasing views permanently cannot be undone. Enter your password to continue.",
|
|
33
|
+
"confirmAction": "Confirm"
|
|
34
|
+
},
|
|
35
|
+
"tabs": {
|
|
36
|
+
"label": "Sections",
|
|
37
|
+
"overview": "Overview",
|
|
38
|
+
"views": "Views",
|
|
39
|
+
"trash": "Trash",
|
|
40
|
+
"trackingLog": "Tracking log",
|
|
41
|
+
"adminLog": "Admin log"
|
|
42
|
+
},
|
|
43
|
+
"common": {
|
|
44
|
+
"none": "-",
|
|
45
|
+
"close": "Close",
|
|
46
|
+
"cancel": "Cancel",
|
|
47
|
+
"dismiss": "Dismiss",
|
|
48
|
+
"yes": "Yes",
|
|
49
|
+
"no": "No"
|
|
50
|
+
},
|
|
51
|
+
"errors": {
|
|
52
|
+
"UNAUTHENTICATED": "Your session has ended. Please sign in again.",
|
|
53
|
+
"INVALID_PASSWORD": "That password is not correct.",
|
|
54
|
+
"TOO_MANY_ATTEMPTS": "Too many failed attempts. Wait a few minutes and try again.",
|
|
55
|
+
"RATE_LIMITED": "Too many requests. Slow down for a moment and try again.",
|
|
56
|
+
"CSRF_REJECTED": "The request was refused for security reasons. Reload the page and try again.",
|
|
57
|
+
"REAUTH_REQUIRED": "Enter your password again to continue.",
|
|
58
|
+
"VALIDATION_FAILED": "The server did not accept that input.",
|
|
59
|
+
"NOT_FOUND": "That was not found.",
|
|
60
|
+
"SERVER_ERROR": "Something went wrong on the server. Please try again.",
|
|
61
|
+
"NETWORK": "The server could not be reached. Check your connection.",
|
|
62
|
+
"ACCESS_EXPIRED": "Your sign-in to the site's access gateway (for example Cloudflare Access) has ended. Reload the page to sign in there again.",
|
|
63
|
+
"UNEXPECTED": "Something went wrong in this page. Reload it and try again."
|
|
64
|
+
},
|
|
65
|
+
"pager": {
|
|
66
|
+
"previous": "Previous",
|
|
67
|
+
"next": "Next",
|
|
68
|
+
"summary": {
|
|
69
|
+
"one": "Page {page} of {pages} · {total} entry",
|
|
70
|
+
"other": "Page {page} of {pages} · {total} entries"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"appTabs": {
|
|
74
|
+
"label": "Apps",
|
|
75
|
+
"tabName": "{app}, {count}",
|
|
76
|
+
"activeCount": {
|
|
77
|
+
"one": "{count} view",
|
|
78
|
+
"other": "{count} views"
|
|
79
|
+
},
|
|
80
|
+
"deletedCount": {
|
|
81
|
+
"one": "{count} in trash",
|
|
82
|
+
"other": "{count} in trash"
|
|
83
|
+
},
|
|
84
|
+
"unavailable": "The table for {app} is missing on the database server.",
|
|
85
|
+
"all": "All apps"
|
|
86
|
+
},
|
|
87
|
+
"toolbar": {
|
|
88
|
+
"search": "Search views",
|
|
89
|
+
"searchPlaceholder": "Search page, title, site, source, campaign, note, event, or view ID…",
|
|
90
|
+
"modifiedFilter": "Filter by admin changes",
|
|
91
|
+
"showDeleted": "Show deleted",
|
|
92
|
+
"pageSize": "Rows per page",
|
|
93
|
+
"perPage": {
|
|
94
|
+
"one": "{count} per page",
|
|
95
|
+
"other": "{count} per page"
|
|
96
|
+
},
|
|
97
|
+
"range": "Date range",
|
|
98
|
+
"eventType": "Event type",
|
|
99
|
+
"allEventTypes": "All event types"
|
|
100
|
+
},
|
|
101
|
+
"modifiedFilter": {
|
|
102
|
+
"any": "All",
|
|
103
|
+
"modified": "Modified",
|
|
104
|
+
"unmodified": "Original"
|
|
105
|
+
},
|
|
106
|
+
"batch": {
|
|
107
|
+
"region": "Actions for selected views",
|
|
108
|
+
"selected": {
|
|
109
|
+
"one": "{count} view selected",
|
|
110
|
+
"other": "{count} views selected"
|
|
111
|
+
},
|
|
112
|
+
"edit": "Edit fields",
|
|
113
|
+
"note": "Set note",
|
|
114
|
+
"delete": "Move to trash",
|
|
115
|
+
"restore": "Restore",
|
|
116
|
+
"purge": "Erase permanently",
|
|
117
|
+
"clear": "Clear selection",
|
|
118
|
+
"limit": {
|
|
119
|
+
"one": "At most {count} view can be selected at once.",
|
|
120
|
+
"other": "At most {count} views can be selected at once."
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"table": {
|
|
124
|
+
"selectPage": "Select every view on this page",
|
|
125
|
+
"selectRow": "Select the view from {time}",
|
|
126
|
+
"empty": "No views match.",
|
|
127
|
+
"emptyTrash": "The trash is empty.",
|
|
128
|
+
"columns": "Columns",
|
|
129
|
+
"columnsTitle": "Columns",
|
|
130
|
+
"columnsIntro": "Tick the columns you want, and put them in order of importance. The table shows as many as fit its width, in this order; the rest of each row is one tap away, under it. Drag a column's edge in the table to change its width.",
|
|
131
|
+
"columnsReset": "Reset to default",
|
|
132
|
+
"columnsApply": "Apply",
|
|
133
|
+
"columnsNone": "Choose at least one column.",
|
|
134
|
+
"moveUp": "Move {column} up",
|
|
135
|
+
"moveDown": "Move {column} down",
|
|
136
|
+
"onlyAllApps": "shown under All apps",
|
|
137
|
+
"resize": "Width of the {column} column",
|
|
138
|
+
"resizeHint": "Drag to resize. Arrow keys also work, and Enter or a double click resets it.",
|
|
139
|
+
"showMore": {
|
|
140
|
+
"one": "Show {count} more field",
|
|
141
|
+
"other": "Show {count} more fields"
|
|
142
|
+
},
|
|
143
|
+
"hideMore": {
|
|
144
|
+
"one": "Hide {count} more field",
|
|
145
|
+
"other": "Hide {count} more fields"
|
|
146
|
+
},
|
|
147
|
+
"showMoreAll": "Show for every row: {columns}",
|
|
148
|
+
"hideMoreAll": "Hide for every row: {columns}"
|
|
149
|
+
},
|
|
150
|
+
"columns": {
|
|
151
|
+
"time": "Time",
|
|
152
|
+
"deleted": "Deleted",
|
|
153
|
+
"app": "App",
|
|
154
|
+
"page": "Page",
|
|
155
|
+
"source": "Source",
|
|
156
|
+
"status": "Status",
|
|
157
|
+
"event": "Event",
|
|
158
|
+
"country": "Location",
|
|
159
|
+
"device": "Device",
|
|
160
|
+
"client": "Client",
|
|
161
|
+
"title": "Title",
|
|
162
|
+
"site": "Site",
|
|
163
|
+
"referrer": "Referrer",
|
|
164
|
+
"campaign": "Campaign",
|
|
165
|
+
"language": "Language",
|
|
166
|
+
"browser": "Browser",
|
|
167
|
+
"system": "System",
|
|
168
|
+
"engagement": "Engagement",
|
|
169
|
+
"ip": "Masked IP",
|
|
170
|
+
"session": "Session ID",
|
|
171
|
+
"viewId": "View ID",
|
|
172
|
+
"note": "Note",
|
|
173
|
+
"modified": "Changed by admin",
|
|
174
|
+
"actions": "Actions"
|
|
175
|
+
},
|
|
176
|
+
"status": {
|
|
177
|
+
"deleted": "In trash",
|
|
178
|
+
"modified": "Modified",
|
|
179
|
+
"note": "Note",
|
|
180
|
+
"repeat": "Repeat"
|
|
181
|
+
},
|
|
182
|
+
"rowActions": {
|
|
183
|
+
"details": "Show details",
|
|
184
|
+
"edit": "Edit fields",
|
|
185
|
+
"note": "Edit note",
|
|
186
|
+
"restore": "Restore",
|
|
187
|
+
"delete": "Move to trash",
|
|
188
|
+
"purge": "Erase permanently"
|
|
189
|
+
},
|
|
190
|
+
"sources": {
|
|
191
|
+
"direct": "Direct",
|
|
192
|
+
"search": "Search",
|
|
193
|
+
"social": "Social",
|
|
194
|
+
"email": "Email",
|
|
195
|
+
"campaign": "Campaign",
|
|
196
|
+
"referral": "Referral",
|
|
197
|
+
"internal": "Internal",
|
|
198
|
+
"unknown": "Unknown"
|
|
199
|
+
},
|
|
200
|
+
"deviceSizes": {
|
|
201
|
+
"small": "Small",
|
|
202
|
+
"medium": "Medium",
|
|
203
|
+
"large": "Large"
|
|
204
|
+
},
|
|
205
|
+
"views": {
|
|
206
|
+
"summary": {
|
|
207
|
+
"one": "{active} view · {modified} modified · {deleted} in trash",
|
|
208
|
+
"other": "{active} views · {modified} modified · {deleted} in trash"
|
|
209
|
+
},
|
|
210
|
+
"intro": "Every view and event the tracker recorded, one row each, newest first. These rows are what every number on the Overview is computed from. Correct a row, add a private note, or move it to the trash; every change is recorded in the Admin log."
|
|
211
|
+
},
|
|
212
|
+
"trash": {
|
|
213
|
+
"retention": {
|
|
214
|
+
"one": "Views in the trash no longer count in any statistic. They are erased permanently {count} day after being deleted, or sooner if you erase them here.",
|
|
215
|
+
"other": "Views in the trash no longer count in any statistic. They are erased permanently {count} days after being deleted, or sooner if you erase them here."
|
|
216
|
+
},
|
|
217
|
+
"retentionOff": "Views in the trash no longer count in any statistic. Automatic erasure is off (TRASH_RETENTION_DAYS=0), so they stay until erased here.",
|
|
218
|
+
"intro": "Views moved to the trash. They no longer count in any statistic and can be restored, or erased for good. Erasing asks for your password again."
|
|
219
|
+
},
|
|
220
|
+
"toasts": {
|
|
221
|
+
"edited": {
|
|
222
|
+
"one": "Edited {count} view.",
|
|
223
|
+
"other": "Edited {count} views."
|
|
224
|
+
},
|
|
225
|
+
"editedPartial": {
|
|
226
|
+
"one": "Edited {count} view; {skipped} skipped because they are in the trash or gone.",
|
|
227
|
+
"other": "Edited {count} views; {skipped} skipped because they are in the trash or gone."
|
|
228
|
+
},
|
|
229
|
+
"noteSaved": {
|
|
230
|
+
"one": "Saved the note on {count} view.",
|
|
231
|
+
"other": "Saved the note on {count} views."
|
|
232
|
+
},
|
|
233
|
+
"noteSavedPartial": {
|
|
234
|
+
"one": "Saved the note on {count} view; {skipped} no longer exist.",
|
|
235
|
+
"other": "Saved the note on {count} views; {skipped} no longer exist."
|
|
236
|
+
},
|
|
237
|
+
"noteCleared": {
|
|
238
|
+
"one": "Cleared the note on {count} view.",
|
|
239
|
+
"other": "Cleared the note on {count} views."
|
|
240
|
+
},
|
|
241
|
+
"noteClearedPartial": {
|
|
242
|
+
"one": "Cleared the note on {count} view; {skipped} no longer exist.",
|
|
243
|
+
"other": "Cleared the note on {count} views; {skipped} no longer exist."
|
|
244
|
+
},
|
|
245
|
+
"deleted": {
|
|
246
|
+
"one": "Moved {count} view to the trash.",
|
|
247
|
+
"other": "Moved {count} views to the trash."
|
|
248
|
+
},
|
|
249
|
+
"deletedPartial": {
|
|
250
|
+
"one": "Moved {count} view to the trash; {skipped} were already there.",
|
|
251
|
+
"other": "Moved {count} views to the trash; {skipped} were already there."
|
|
252
|
+
},
|
|
253
|
+
"restored": {
|
|
254
|
+
"one": "Restored {count} view.",
|
|
255
|
+
"other": "Restored {count} views."
|
|
256
|
+
},
|
|
257
|
+
"restoredPartial": {
|
|
258
|
+
"one": "Restored {count} view; {skipped} were not in the trash.",
|
|
259
|
+
"other": "Restored {count} views; {skipped} were not in the trash."
|
|
260
|
+
},
|
|
261
|
+
"purged": {
|
|
262
|
+
"one": "Erased {count} view permanently.",
|
|
263
|
+
"other": "Erased {count} views permanently."
|
|
264
|
+
},
|
|
265
|
+
"purgedPartial": {
|
|
266
|
+
"one": "Erased {count} view permanently; {skipped} were not in the trash.",
|
|
267
|
+
"other": "Erased {count} views permanently; {skipped} were not in the trash."
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
"confirm": {
|
|
271
|
+
"deleteTitle": {
|
|
272
|
+
"one": "Move {count} view to the trash?",
|
|
273
|
+
"other": "Move {count} views to the trash?"
|
|
274
|
+
},
|
|
275
|
+
"deleteMessage": {
|
|
276
|
+
"one": "It stops counting in every statistic at once. You can restore it from the trash within {days} days, after which it is erased for good.",
|
|
277
|
+
"other": "They stop counting in every statistic at once. You can restore them from the trash within {days} days, after which they are erased for good."
|
|
278
|
+
},
|
|
279
|
+
"deleteMessageNoRetention": {
|
|
280
|
+
"one": "It stops counting in every statistic at once. You can restore it from the trash at any time.",
|
|
281
|
+
"other": "They stop counting in every statistic at once. You can restore them from the trash at any time."
|
|
282
|
+
},
|
|
283
|
+
"deleteAction": "Move to trash",
|
|
284
|
+
"purgeTitle": {
|
|
285
|
+
"one": "Erase {count} view permanently?",
|
|
286
|
+
"other": "Erase {count} views permanently?"
|
|
287
|
+
},
|
|
288
|
+
"purgeMessage": {
|
|
289
|
+
"one": "This removes the view from the database for good. It cannot be restored. The admin log keeps a record that it was erased, but none of its content.",
|
|
290
|
+
"other": "This removes the views from the database for good. They cannot be restored. The admin log keeps a record that they were erased, but none of their content."
|
|
291
|
+
},
|
|
292
|
+
"purgeAction": "Erase permanently"
|
|
293
|
+
},
|
|
294
|
+
"details": {
|
|
295
|
+
"title": "View details",
|
|
296
|
+
"scrolled": "{percent}% of the page",
|
|
297
|
+
"groups": {
|
|
298
|
+
"view": "View",
|
|
299
|
+
"page": "Page",
|
|
300
|
+
"source": "Source and campaign",
|
|
301
|
+
"visitor": "Visitor",
|
|
302
|
+
"engagement": "Engagement",
|
|
303
|
+
"admin": "Admin changes"
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
"fields": {
|
|
307
|
+
"id": "View ID",
|
|
308
|
+
"timestamp": "Recorded at",
|
|
309
|
+
"pagePath": "Page path",
|
|
310
|
+
"pageTitle": "Page title",
|
|
311
|
+
"referrer": "Referrer",
|
|
312
|
+
"referrerDomain": "Referrer domain",
|
|
313
|
+
"sourceType": "Source",
|
|
314
|
+
"deviceSize": "Device size",
|
|
315
|
+
"deviceType": "Device type",
|
|
316
|
+
"country": "Country",
|
|
317
|
+
"maskedIp": "Masked IP",
|
|
318
|
+
"browser": "Browser",
|
|
319
|
+
"browserVersion": "Browser version",
|
|
320
|
+
"os": "Operating system",
|
|
321
|
+
"osVersion": "OS version",
|
|
322
|
+
"sessionId": "Session ID (sent by the site)",
|
|
323
|
+
"eventType": "Event type",
|
|
324
|
+
"eventData": "Event data",
|
|
325
|
+
"isUnique": "Unique view",
|
|
326
|
+
"note": "Note",
|
|
327
|
+
"adminModifiedAt": "Modified by admin",
|
|
328
|
+
"deletedAt": "Moved to trash",
|
|
329
|
+
"hostname": "Site (hostname)",
|
|
330
|
+
"language": "Language",
|
|
331
|
+
"utmSource": "Campaign source",
|
|
332
|
+
"utmMedium": "Campaign medium",
|
|
333
|
+
"utmCampaign": "Campaign name",
|
|
334
|
+
"utmTerm": "Campaign term",
|
|
335
|
+
"utmContent": "Campaign content",
|
|
336
|
+
"region": "Region",
|
|
337
|
+
"city": "City",
|
|
338
|
+
"engagedMs": "Time on page",
|
|
339
|
+
"scrollDepth": "Scroll depth"
|
|
340
|
+
},
|
|
341
|
+
"edit": {
|
|
342
|
+
"titleSingle": "Edit view",
|
|
343
|
+
"titleBatch": {
|
|
344
|
+
"one": "Edit {count} view",
|
|
345
|
+
"other": "Edit {count} views"
|
|
346
|
+
},
|
|
347
|
+
"introSingle": "Change a field and it is saved. The view is then marked as modified by an admin.",
|
|
348
|
+
"introBatch": {
|
|
349
|
+
"one": "Tick each field to overwrite on the selected view. Unticked fields are left alone.",
|
|
350
|
+
"other": "Tick each field to overwrite on all {count} selected views. Unticked fields are left alone."
|
|
351
|
+
},
|
|
352
|
+
"lockedNotice": "What was observed about the visitor (time, masked IP, country, browser, device type) can never be edited. The source is recalculated from the referrer.",
|
|
353
|
+
"include": "Change {field}",
|
|
354
|
+
"invalidJson": "This is not valid JSON.",
|
|
355
|
+
"nothingSelected": "Choose at least one field to change.",
|
|
356
|
+
"save": "Save changes"
|
|
357
|
+
},
|
|
358
|
+
"note": {
|
|
359
|
+
"titleSingle": "Note",
|
|
360
|
+
"titleBatch": {
|
|
361
|
+
"one": "Note for {count} view",
|
|
362
|
+
"other": "Note for {count} views"
|
|
363
|
+
},
|
|
364
|
+
"intro": "A private annotation for admins. Adding a note does not mark a view as modified.",
|
|
365
|
+
"clear": "Clear note",
|
|
366
|
+
"save": "Save note"
|
|
367
|
+
},
|
|
368
|
+
"logs": {
|
|
369
|
+
"filterAction": "Filter by action",
|
|
370
|
+
"allActions": "All actions",
|
|
371
|
+
"filterApp": "Filter by app",
|
|
372
|
+
"allApps": "All apps",
|
|
373
|
+
"filterSource": "Filter by request type",
|
|
374
|
+
"allSources": "All request types",
|
|
375
|
+
"filterOutcome": "Filter by outcome",
|
|
376
|
+
"allOutcomes": "All outcomes",
|
|
377
|
+
"system": "system",
|
|
378
|
+
"emptyAdmin": "No admin operations recorded yet.",
|
|
379
|
+
"emptyTracking": "No tracking requests match.",
|
|
380
|
+
"adminIntro": "Everything done in this admin: sign-ins, edits, notes, moves to the trash, restores, and erasures, with the session and the masked address it came from. It never records what a view said, so an erased view leaves no trace of its content.",
|
|
381
|
+
"trackingIntro": "Every tracking request that reached the server, and what became of it. Views lists only what was recorded, and the Overview counts only that. This log also shows what was never stored: bots, and requests refused (an unregistered site, an unknown app, a malformed request). Use it to check that a site is sending views and to find out why some are not counted. Editing or deleting a view never changes it.",
|
|
382
|
+
"trackingRetention": {
|
|
383
|
+
"one": "Entries are removed automatically {count} day after they are recorded. Views are not affected.",
|
|
384
|
+
"other": "Entries are removed automatically {count} days after they are recorded. Views are not affected."
|
|
385
|
+
},
|
|
386
|
+
"trackingRetentionOff": "Entries are kept until removed by hand (VIEW_LOG_RETENTION_DAYS=0).",
|
|
387
|
+
"outcomesTitle": "What each outcome means",
|
|
388
|
+
"outcomeHelp": {
|
|
389
|
+
"recorded": "Stored as a view, and counted as a unique view.",
|
|
390
|
+
"repeat": "Stored as a view, from a visitor already counted in this window, so not counted as unique.",
|
|
391
|
+
"bot": "A crawler, preview fetcher, or automated browser. Never stored; counted here by name, per minute.",
|
|
392
|
+
"rejected": "Refused and never stored; the reason is shown. Counted per minute, without anything about the requester."
|
|
393
|
+
},
|
|
394
|
+
"lastHours": {
|
|
395
|
+
"one": "last {count} hour",
|
|
396
|
+
"other": "last {count} hours"
|
|
397
|
+
},
|
|
398
|
+
"summaryLabel": {
|
|
399
|
+
"one": "Tracking requests in the last {count} hour",
|
|
400
|
+
"other": "Tracking requests in the last {count} hours"
|
|
401
|
+
},
|
|
402
|
+
"reasons": "Refused in the last day: {list}",
|
|
403
|
+
"noReasons": "Nothing refused in the last day.",
|
|
404
|
+
"autoRefresh": "Refresh every {seconds} s",
|
|
405
|
+
"openView": "Show this view",
|
|
406
|
+
"openViewNamed": "Show view {id}"
|
|
407
|
+
},
|
|
408
|
+
"logColumns": {
|
|
409
|
+
"time": "Time",
|
|
410
|
+
"action": "Action",
|
|
411
|
+
"app": "App",
|
|
412
|
+
"rows": "Rows",
|
|
413
|
+
"fields": "Fields",
|
|
414
|
+
"session": "Session",
|
|
415
|
+
"ip": "IP (masked)",
|
|
416
|
+
"source": "Request",
|
|
417
|
+
"outcome": "Outcome",
|
|
418
|
+
"detail": "Reason or detail",
|
|
419
|
+
"view": "View",
|
|
420
|
+
"site": "Site",
|
|
421
|
+
"event": "Event",
|
|
422
|
+
"requests": "Requests"
|
|
423
|
+
},
|
|
424
|
+
"actions": {
|
|
425
|
+
"login_succeeded": "Signed in",
|
|
426
|
+
"login_failed": "Failed sign-in",
|
|
427
|
+
"logout": "Signed out",
|
|
428
|
+
"views_edited": "Edited",
|
|
429
|
+
"note_set": "Note set",
|
|
430
|
+
"note_cleared": "Note cleared",
|
|
431
|
+
"views_deleted": "Moved to trash",
|
|
432
|
+
"views_restored": "Restored",
|
|
433
|
+
"views_purged": "Erased",
|
|
434
|
+
"trash_auto_purged": "Trash auto-erased",
|
|
435
|
+
"view_log_pruned": "Tracking log pruned",
|
|
436
|
+
"password_confirmed": "Password confirmed"
|
|
437
|
+
},
|
|
438
|
+
"outcomes": {
|
|
439
|
+
"recorded": "Recorded",
|
|
440
|
+
"repeat": "Repeat visit",
|
|
441
|
+
"bot": "Bot",
|
|
442
|
+
"rejected": "Refused"
|
|
443
|
+
},
|
|
444
|
+
"rejectionReasons": {
|
|
445
|
+
"bot": "automated client",
|
|
446
|
+
"unknown_app": "unknown app",
|
|
447
|
+
"origin_not_allowed": "site not allowed",
|
|
448
|
+
"invalid_request": "invalid request",
|
|
449
|
+
"invalid_ip": "unreadable IP address",
|
|
450
|
+
"rate_limited": "rate limited",
|
|
451
|
+
"unknown_view": "view not found",
|
|
452
|
+
"server_error": "server error"
|
|
453
|
+
},
|
|
454
|
+
"logSources": {
|
|
455
|
+
"registerView": "Page view",
|
|
456
|
+
"event": "Event",
|
|
457
|
+
"engage": "Engagement"
|
|
458
|
+
},
|
|
459
|
+
"ranges": {
|
|
460
|
+
"24h": "24 hours",
|
|
461
|
+
"7d": "7 days",
|
|
462
|
+
"30d": "30 days",
|
|
463
|
+
"90d": "90 days",
|
|
464
|
+
"1y": "1 year",
|
|
465
|
+
"all": "All time"
|
|
466
|
+
},
|
|
467
|
+
"eventTypes": {
|
|
468
|
+
"pageview": "Page view",
|
|
469
|
+
"outbound": "Link to another site",
|
|
470
|
+
"download": "Download"
|
|
471
|
+
},
|
|
472
|
+
"deviceTypes": {
|
|
473
|
+
"desktop": "Desktop",
|
|
474
|
+
"mobile": "Phone",
|
|
475
|
+
"tablet": "Tablet",
|
|
476
|
+
"wearable": "Wearable",
|
|
477
|
+
"tv": "TV",
|
|
478
|
+
"console": "Games console"
|
|
479
|
+
},
|
|
480
|
+
"charts": {
|
|
481
|
+
"views": "Views",
|
|
482
|
+
"share": "of views",
|
|
483
|
+
"noData": "No views match these filters.",
|
|
484
|
+
"showTable": "Table",
|
|
485
|
+
"showChart": "Chart",
|
|
486
|
+
"period": "Period",
|
|
487
|
+
"weekOf": "Week of {date}",
|
|
488
|
+
"inProgress": "{period} (so far)",
|
|
489
|
+
"trendLabel": "{metric} from {from} to {to}, highest at {peak} on {peakAt}. Use the arrow keys to read each period.",
|
|
490
|
+
"topCountries": "Countries by views",
|
|
491
|
+
"mapLabel": "World map of views by country, {countries} countries with views. The list beside it gives the numbers.",
|
|
492
|
+
"mapUnavailable": "The map could not be loaded. The list beside it has every number.",
|
|
493
|
+
"noViews": "No views",
|
|
494
|
+
"otherTypes": "Other types",
|
|
495
|
+
"moreCountries": {
|
|
496
|
+
"one": "Show {count} more country",
|
|
497
|
+
"other": "Show {count} more countries"
|
|
498
|
+
},
|
|
499
|
+
"fewerCountries": "Show fewer",
|
|
500
|
+
"heatmapLabel": "Views by weekday and hour, busiest on {day} at {hour} with {views} views. Use the arrow keys to read each hour, or switch to the table.",
|
|
501
|
+
"heatmapCell": "{day}, {from} to {to}",
|
|
502
|
+
"hour": "Hour",
|
|
503
|
+
"minutesLabel": "Views per minute over the last {count} minutes, {views} in all. Use the arrow keys to read each minute.",
|
|
504
|
+
"minutesAgo": {
|
|
505
|
+
"one": "{count} minute ago",
|
|
506
|
+
"other": "{count} minutes ago"
|
|
507
|
+
},
|
|
508
|
+
"now": "Now"
|
|
509
|
+
},
|
|
510
|
+
"overview": {
|
|
511
|
+
"intro": "Statistics for the app and period chosen below, computed from live views only (the trash never counts). Click any row in a breakdown to narrow everything to it.",
|
|
512
|
+
"showViews": "Show these views",
|
|
513
|
+
"removeFilter": "Remove the filter {filter}",
|
|
514
|
+
"clearFilters": "Clear filters",
|
|
515
|
+
"filterBy": "Show only {dimension}: {value}",
|
|
516
|
+
"cardView": "{card}: what to show",
|
|
517
|
+
"trendTitle": "{metric} over time",
|
|
518
|
+
"trendView": "Show the trend as",
|
|
519
|
+
"tilesLabel": "Headline numbers. Choose one to chart it over time.",
|
|
520
|
+
"span": {
|
|
521
|
+
"one": "From {from} to {to} · {countries} country · {unique} unique views · {modified} changed by an admin",
|
|
522
|
+
"other": "From {from} to {to} · {countries} countries · {unique} unique views · {modified} changed by an admin"
|
|
523
|
+
},
|
|
524
|
+
"empty": "No views match these filters.",
|
|
525
|
+
"allTime": "All time",
|
|
526
|
+
"noComparison": "Nothing to compare with",
|
|
527
|
+
"vsPrevious": {
|
|
528
|
+
"24h": "vs the 24 hours before",
|
|
529
|
+
"7d": "vs the 7 days before",
|
|
530
|
+
"30d": "vs the 30 days before",
|
|
531
|
+
"90d": "vs the 90 days before",
|
|
532
|
+
"1y": "vs the year before"
|
|
533
|
+
},
|
|
534
|
+
"points": "{value} pts",
|
|
535
|
+
"deltaNew": "New",
|
|
536
|
+
"helpTitle": "How these numbers are counted",
|
|
537
|
+
"metrics": {
|
|
538
|
+
"visitors": "Visitors",
|
|
539
|
+
"visits": "Visits",
|
|
540
|
+
"pageviews": "Page views",
|
|
541
|
+
"views": "Views and events",
|
|
542
|
+
"bounceRate": "Bounce rate",
|
|
543
|
+
"avgVisitMs": "Visit duration",
|
|
544
|
+
"pagesPerVisit": "Pages per visit",
|
|
545
|
+
"avgEngagedMs": "Time on page",
|
|
546
|
+
"avgScroll": "Scroll depth"
|
|
547
|
+
},
|
|
548
|
+
"help": {
|
|
549
|
+
"visitors": "Distinct visitors, told apart by a hash of the address and browser that changes every day and is never stored with anything that identifies a person. The same person on two days counts twice, and people sharing a network and browser count once.",
|
|
550
|
+
"visits": "Page views of one visitor with no pause longer than 30 minutes between them.",
|
|
551
|
+
"pageviews": "Views of a page, without custom events.",
|
|
552
|
+
"views": "Everything recorded: page views and custom events such as downloads or clicks on links to other sites.",
|
|
553
|
+
"bounceRate": "The share of visits that saw only one page.",
|
|
554
|
+
"avgVisitMs": "From the first page view of a visit to the last, plus how long the last page was visible. The average over visits.",
|
|
555
|
+
"pagesPerVisit": "Page views per visit, on average.",
|
|
556
|
+
"avgEngagedMs": "How long a page was actually visible on screen, as the tracker script measured it. Only pages with a measurement count.",
|
|
557
|
+
"avgScroll": "How much of a page had been on screen, at most, as the tracker script measured it."
|
|
558
|
+
},
|
|
559
|
+
"dims": {
|
|
560
|
+
"source": "Channel",
|
|
561
|
+
"referrer": "Referrer",
|
|
562
|
+
"referrerUrl": "Referring page",
|
|
563
|
+
"utmSource": "Campaign source",
|
|
564
|
+
"utmMedium": "Campaign medium",
|
|
565
|
+
"utmCampaign": "Campaign",
|
|
566
|
+
"utmTerm": "Campaign term",
|
|
567
|
+
"utmContent": "Campaign content",
|
|
568
|
+
"page": "Page",
|
|
569
|
+
"title": "Title",
|
|
570
|
+
"hostname": "Site",
|
|
571
|
+
"country": "Country",
|
|
572
|
+
"region": "Region",
|
|
573
|
+
"city": "City",
|
|
574
|
+
"language": "Language",
|
|
575
|
+
"deviceSize": "Screen size",
|
|
576
|
+
"deviceType": "Device type",
|
|
577
|
+
"browser": "Browser",
|
|
578
|
+
"browserVersion": "Browser version",
|
|
579
|
+
"os": "Operating system",
|
|
580
|
+
"osVersion": "System version",
|
|
581
|
+
"eventType": "Event type",
|
|
582
|
+
"app": "App",
|
|
583
|
+
"timeOnPage": "Time on page",
|
|
584
|
+
"scrollDepth": "Scrolled"
|
|
585
|
+
},
|
|
586
|
+
"noReferrer": "Direct or not sent",
|
|
587
|
+
"notTagged": "Not tagged",
|
|
588
|
+
"noTitle": "No title",
|
|
589
|
+
"unknown": "Unknown",
|
|
590
|
+
"other": "Everything else",
|
|
591
|
+
"columns": {
|
|
592
|
+
"visitors": "Visitors",
|
|
593
|
+
"views": "Views",
|
|
594
|
+
"share": "Share",
|
|
595
|
+
"visits": "Visits",
|
|
596
|
+
"bounceRate": "Bounce",
|
|
597
|
+
"timeOnPage": "Time",
|
|
598
|
+
"scroll": "Scroll",
|
|
599
|
+
"steps": "Times",
|
|
600
|
+
"count": "Count",
|
|
601
|
+
"pageviews": "Page views"
|
|
602
|
+
},
|
|
603
|
+
"noVisits": "No page views, so no visits, match these filters.",
|
|
604
|
+
"noFlow": "No visitor went from one page to another in these views.",
|
|
605
|
+
"noProperties": "No custom event carried properties in these views.",
|
|
606
|
+
"noEngagement": "No time or scrolling measured yet. The tracker script measures both; a site that registers views another way does not.",
|
|
607
|
+
"noCityData": "Regions and cities need a city database on the server (GEOIP_CITY_DB). Countries work without one.",
|
|
608
|
+
"flowHeader": "From page, to page",
|
|
609
|
+
"flowStep": "{from} → {to}",
|
|
610
|
+
"propertyHeader": "Property",
|
|
611
|
+
"property": "{key} = {value}",
|
|
612
|
+
"orMore": "{from} or more",
|
|
613
|
+
"under": "Under {to}",
|
|
614
|
+
"between": "{from} to {to}",
|
|
615
|
+
"scrollAll": "All of it (100%)",
|
|
616
|
+
"scrollBetween": "{from}% to {to}%",
|
|
617
|
+
"cards": {
|
|
618
|
+
"apps": "Apps",
|
|
619
|
+
"sources": "Sources",
|
|
620
|
+
"pages": "Pages",
|
|
621
|
+
"locations": "Locations",
|
|
622
|
+
"devices": "Devices",
|
|
623
|
+
"browsers": "Browsers",
|
|
624
|
+
"systems": "Operating systems",
|
|
625
|
+
"campaigns": "Campaigns",
|
|
626
|
+
"events": "Events",
|
|
627
|
+
"engagement": "Engagement",
|
|
628
|
+
"when": "When, by weekday and hour ({zone})",
|
|
629
|
+
"flow": "Page flow"
|
|
630
|
+
},
|
|
631
|
+
"tabs": {
|
|
632
|
+
"channels": "Channels",
|
|
633
|
+
"referrers": "Referrers",
|
|
634
|
+
"referringPages": "Referring pages",
|
|
635
|
+
"topPages": "Top",
|
|
636
|
+
"entryPages": "Entry",
|
|
637
|
+
"exitPages": "Exit",
|
|
638
|
+
"titles": "Titles",
|
|
639
|
+
"sites": "Sites",
|
|
640
|
+
"map": "Map",
|
|
641
|
+
"countries": "Countries",
|
|
642
|
+
"regions": "Regions",
|
|
643
|
+
"cities": "Cities",
|
|
644
|
+
"languages": "Languages",
|
|
645
|
+
"screenSizes": "Screen sizes",
|
|
646
|
+
"deviceTypes": "Device types",
|
|
647
|
+
"browsers": "Browsers",
|
|
648
|
+
"versions": "Versions",
|
|
649
|
+
"systems": "Systems",
|
|
650
|
+
"utmSource": "Source",
|
|
651
|
+
"utmMedium": "Medium",
|
|
652
|
+
"utmCampaign": "Campaign",
|
|
653
|
+
"utmTerm": "Term",
|
|
654
|
+
"utmContent": "Content",
|
|
655
|
+
"eventTypes": "Types",
|
|
656
|
+
"properties": "Properties",
|
|
657
|
+
"timeOnPage": "Time on page",
|
|
658
|
+
"scrollDepth": "Scroll depth"
|
|
659
|
+
},
|
|
660
|
+
"whenNote": "Covers up to the last year of the chosen period, in your time zone.",
|
|
661
|
+
"live": {
|
|
662
|
+
"title": "Right now",
|
|
663
|
+
"visitors": {
|
|
664
|
+
"one": "visitor in the last {minutes} minutes",
|
|
665
|
+
"other": "visitors in the last {minutes} minutes"
|
|
666
|
+
},
|
|
667
|
+
"pages": "Pages open now",
|
|
668
|
+
"nobody": "Nobody on the sites right now.",
|
|
669
|
+
"updated": "Updated {time}, every {seconds} s while this page is open. Live views of the chosen app; the filters above do not apply."
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
"footer": {
|
|
673
|
+
"product": "Version {version}",
|
|
674
|
+
"links": "About viewcounter",
|
|
675
|
+
"website": "Website",
|
|
676
|
+
"docs": "Admin guide",
|
|
677
|
+
"changelog": "Changelog",
|
|
678
|
+
"source": "Source code",
|
|
679
|
+
"npm": "npm package",
|
|
680
|
+
"credits": "Location data:",
|
|
681
|
+
"copyright": "{product} © {year} {holder}"
|
|
682
|
+
}
|
|
683
|
+
}
|