Compare commits

...

102 Commits

Author SHA1 Message Date
Andrey Meshkov
a33164bf18 Merge CI revamped and other enhancements
GoReleaser for multi-arch binaries
Switch to GitHub Actions (more versatile) with 2 workflows
Docker multi-manifest image with buildx
Fix eslint run script
Use tools.go paradigm for external dependencies (packr)
Use go generate for packr
Enhanced Dockerfile

Co-authored-by: CrazyMax crazy-max@users.noreply.github.com

* commit 'c2642cc58ece302182148c7126d3b9b1176166a8':
  fix GH actions snapshot build
  Removed snapshot target
  Updated links to beta&edge versions in README
  Excluded some paths from golang linter
  Fix version check when req body is empty
  Don't set the version tag for edge channel
  don't fail on packr
  fix packr detect
  Improve makefile clean target
  Fix project name, update README
  CI revamp part 2 (#1875)
  CI Revamp by @crazy-max (#1873)
2020-07-13 12:02:43 +03:00
Andrey Meshkov
c2642cc58e fix GH actions snapshot build 2020-07-10 23:54:02 +03:00
Andrey Meshkov
6811d6207a Removed snapshot target 2020-07-10 23:24:43 +03:00
Andrey Meshkov
1fe568b842 Updated links to beta&edge versions in README 2020-07-10 22:21:11 +03:00
Andrey Meshkov
f6217e602b Excluded some paths from golang linter 2020-07-10 22:20:46 +03:00
Andrey Meshkov
fdf608904d Fix version check when req body is empty 2020-07-10 22:20:30 +03:00
Andrey Meshkov
ab401cabe2 Don't set the version tag for edge channel 2020-07-10 18:28:09 +03:00
Andrey Meshkov
0be0299135 don't fail on packr 2020-07-10 17:18:04 +03:00
Andrey Meshkov
dc5c89795b fix packr detect 2020-07-10 17:10:11 +03:00
Andrey Meshkov
db0283098c Improve makefile clean target 2020-07-10 16:58:52 +03:00
Andrey Meshkov
2bbffffcfc Fix project name, update README 2020-07-10 14:57:53 +03:00
Andrey Meshkov
632a47d56f CI revamp part 2 (#1875)
* Added Makefile
* Updated README with the new information
* Updated Github Actions
* Added FreeBSD ARM builds
* Prepared to our internal CI
* Improved the auto-update version check
2020-07-09 19:54:53 +03:00
Andrey Meshkov
ff23d7b6d7 CI Revamp by @crazy-max (#1873)
* CI revamped and other enhancements
GoReleaser for multi-arch binaries
Switch to GitHub Actions (more versatile) with 2 workflows
Docker multi-manifest image with buildx
Fix eslint run script
Go sum fixer
Use tools.go paradigm for external dependencies (packr)
Use go generate for packr

* Update workflows
* Add Slack notification
* Rebase
* Enhanced Dockerfile
* Fix go generate
* Fix Golangci lint
* Fix npm cache with v2 cache action
* Fix Dockerfile
* Trigger notif
* Issue with packr
* s390x platform not supported by packr
* Enhance layers
* Fix go modules

Co-authored-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-07-09 11:53:41 +03:00
Andrey Meshkov
304a51f17e *(home): added anti-AD regional filter list
Closes: https://github.com/AdguardTeam/AdGuardHome/issues/1357
2020-07-08 10:57:46 +03:00
Andrey Meshkov
5d08e08a7a Merge branch 'patch-1' of git://github.com/ZusorCode/AdGuardHome into ZusorCode-patch-1 2020-07-08 10:31:23 +03:00
Andrey Meshkov
49646cf706 + client: Add choosing filter lists
Fix #1325

Squashed commit of the following:

commit d8f7de72226855a961051e09b4b78f4dd71baadd
Merge: f9bbe861 36f3218b
Author: Andrey Meshkov <am@adguard.com>
Date:   Mon Jul 6 19:34:53 2020 +0300

    Merge branch 'master' into feature/1325

commit f9bbe861c9dbd631b5708f8eb073270b83a3f70f
Merge: 99710fef 4f8138bd
Author: Andrey Meshkov <am@adguard.com>
Date:   Mon Jul 6 19:33:53 2020 +0300

    Merge branch 'master' into feature/1325

commit 99710fef0825966b224e4a30a979e4d45f929af1
Merge: 8329326d a5380ead
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jul 6 18:04:32 2020 +0300

    Merge branch 'feature/1325' of ssh://bit.adguard.com:7999/dns/adguard-home into feature/1325

commit 8329326d6470dfcf2cdc4479e0290f7cc56ddca4
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jul 6 18:03:56 2020 +0300

    Update locales, add title for select modal

commit a5380ead56d15eba3f36c38f8fc0eedc89c2c57a
Author: Andrey Meshkov <am@adguard.com>
Date:   Mon Jul 6 17:26:37 2020 +0300

    Update readme

commit dfe6e254d909ee6994cacef53d417bb073dfd802
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jul 6 13:44:19 2020 +0300

    Change info icon width

commit 06120cf3da9065fc9cc3a2864b976563d4cfe06a
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jul 6 13:38:58 2020 +0300

    Review changes

commit ae3c6cacc5610a0f95bec2f6ef8a63e90041e4dd
Merge: dd56a3bb 73c5d9ea
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jul 6 12:01:57 2020 +0300

    Merge branch 'master' into feature/1325

commit dd56a3bbb851687823242fa653cc3bb63dedf5e4
Author: Andrey Meshkov <am@adguard.com>
Date:   Fri Jul 3 15:52:01 2020 +0300

    Added blocklists

commit f08f0eb0cdd8cd488d3a8f1182854b72775cf06e
Merge: 854d4f88 21dfb5ff
Author: Andrey Meshkov <am@adguard.com>
Date:   Fri Jul 3 14:06:19 2020 +0300

    Merge branch 'master' into feature/1325

commit 854d4f88017a33dc7f788835dc98591cec9b213f
Merge: 23946266 2c47053c
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jun 22 14:09:31 2020 +0300

    Merge branch 'master' into feature/1325

commit 23946266d4913479bcecfcb7702a096983d20685
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue May 26 19:00:26 2020 +0300

    Math filters by url

commit 661e0482f01ffea0d0f5aa81b3b253143d0ca112
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon May 25 21:07:21 2020 +0300

    Change data format

commit ac4ff483b6b06ec0be49a41b5ddd3329f4ae2bbb
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu May 14 19:52:45 2020 +0300

    + client: Add choosing filter lists
2020-07-06 19:58:44 +03:00
Andrey Meshkov
36f3218b1c - client: Fix mobile query log
Fix #1828

* commit '036ab4128df678f5aa6037f6ad622e8f428c5efa':
  - client: Fix mobile query log
2020-07-06 19:34:41 +03:00
ArtemBaskal
036ab4128d - client: Fix mobile query log 2020-07-06 19:28:07 +03:00
Andrey Meshkov
4f8138bdce Fix #1764
+ rewrites: support IP exception; support "pass A only" case

* commit '32610840f9a0769bb58c7443a485c5e5b0cd2b68':
  + rewrites: support IP exception; support "pass A only" case
2020-07-06 17:00:10 +03:00
Artem Baskal
73c5d9eaef - client: Improve DNS Rewrites
Close #1764

Squashed commit of the following:

commit 76af537597b2f3c0860716a45e4e23662cde22c8
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jul 6 10:59:44 2020 +0300

    - client: Improve DNS Rewrites
2020-07-06 11:23:23 +03:00
Andrey Meshkov
32610840f9 Merge 1764 Improve DNS Rewrites
* commit '5980db1a2d00b9f94a7401530a7ba1437c32efb6':
  + rewrites: support IP exception; support "pass A only" case
2020-07-06 01:38:07 +03:00
Andrey Meshkov
2f76f5d048 Merge: Fix #1587 UI + dns: new settings for cache
* commit '7dd3d944e86808412b82d7e0d804ef1909443e81':
  Extract validation functions in the separate file
  Add DNS cache setting UI
  + dns: new settings for cache
2020-07-06 01:37:39 +03:00
ArtemBaskal
7dd3d944e8 Merge branch 'master' into 1587-cache-settings 2020-07-03 22:30:56 +03:00
Andrey Meshkov
48f40d5f01 Merge: fix #1587 + dns: new settings for cache
* commit '4303b3dd2f6c4e1f64e8cd8575070de35b3d6df7':
  + dns: new settings for cache
2020-07-03 20:54:25 +03:00
Simon Zolin
4303b3dd2f + dns: new settings for cache
Squashed commit of the following:

commit e5b488249a4d972efd63c6e96830d9f30829aee1
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jun 16 15:38:27 2020 +0300

    + dns: new settings for cache
2020-07-03 20:35:04 +03:00
Simon Zolin
dab0a9d87a + "--glinet" command-line argument: Run in GL-Inet compatibility mode
Close #1853

Squashed commit of the following:

commit 3730cafabe8fa1dbf2bf75915079d2effe4ff9a3
Merge: 533ae3c2 6b134469
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 19:21:08 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1853-glinet

commit 533ae3c2678cd6cfd26bf9560bee4eb5a015a615
Merge: 3521992b 21dfb5ff
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 19:14:45 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1853-glinet

commit 3521992b4609fa3400942c89f7a7546dade459bc
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 18:04:53 2020 +0300

    logs

commit 3e0258782b1a14c08156fe65940ae7b661a42b54
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 17:11:47 2020 +0300

    fix

commit bb814db9df1c770d0ea02eafd12bedd122bef894
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 16:58:37 2020 +0300

    minor

commit b161bbc5749ce76b16600e0153120935ad20077e
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 16:53:22 2020 +0300

    move code

commit c506e81265bdee140c0f61255f927c13738efc1a
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jul 2 10:50:56 2020 +0300

    test

commit c09f201cbd88498a2328be332197e4d96e5fb115
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jul 2 10:42:23 2020 +0300

    + "--glinet" command-line argument: Run in GL-Inet compatibility mode
2020-07-03 20:34:08 +03:00
Artem Baskal
6b134469d4 - client: Clear input field when switching from logs page
Close #1523

Squashed commit of the following:

commit 9ae9b0e480c2ec6bd835faf4caccacd8c1fdfe9f
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 17:56:34 2020 +0300

    Setup babel and apply everywhere nullish coalescing and optional chaining operators

commit 0966063842a79078e1d61a54c271e18c9427b2b1
Merge: 42a54f2b 21dfb5ff
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 16:59:34 2020 +0300

    Merge branch 'master' into fix/1523

commit 42a54f2ba0d8f5f4e4c04f16abc507b5d9009035
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 13:30:25 2020 +0300

    Center mobile tooltip buttons

commit 9cdd501a863b596f1d903f8dd3c449ffbe4c1604
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 13:21:37 2020 +0300

    Add cross icon to clear input on click

commit 1308b93c42ffea2ffb7457c34aef96e5cdaccaf2
Merge: 265fec7c da546790
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jun 29 19:42:04 2020 +0300

    Merge branch 'master' of ssh://bit.adguard.com:7999/dns/adguard-home

commit 265fec7c72656b0c4738623cb470f1c14736230a
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jun 29 19:41:37 2020 +0300

    - client: Clear input field when switching from logs page
2020-07-03 19:17:58 +03:00
ArtemBaskal
0c4905fa2b Extract validation functions in the separate file 2020-07-03 19:10:05 +03:00
Simon Zolin
5980db1a2d + rewrites: support IP exception; support "pass A only" case
+ rewrites: support IP exception

	host.com -> 1.2.3.4
	host.com -> AAAA

Response:

	A:
		A = 1.2.3.4
	AAAA:
		AAAA = <IPv6 address of host.com>

+ rewrites: support "pass A only" case

	host.com -> A

Response:

	A:
		A = <IPv4 address of host.com>
	AAAA:
		<empty>
2020-07-03 17:37:51 +03:00
ArtemBaskal
c12309a1b2 Resolve conflict 2020-07-03 16:58:23 +03:00
ArtemBaskal
2d5287fcf3 Add DNS cache setting UI 2020-07-03 16:53:53 +03:00
Simon Zolin
21dfb5ffe8 * querylog: case-insensitive search by domain name
Close #1828

Squashed commit of the following:

commit 347aff1f8c5293bd06ecc0693970fe447b6e2c75
Merge: f07c8dc0 9df7aba9
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 12:10:02 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1828-qlog-case-insens

commit f07c8dc0665585ce00c415293c47c5a8c9724881
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jul 3 12:09:49 2020 +0300

    minor

commit 512c7acd48f649a0d11b4fef66a1351fcd19635b
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jul 2 19:01:43 2020 +0300

    minor

commit 9f5700af56340c38a2d892101e32959702816205
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jul 2 16:53:56 2020 +0300

    * querylog: case-insensitive search by domain name
2020-07-03 12:21:09 +03:00
Artem Baskal
9df7aba9e1 - client: Fix client tracker source links
Close #1813

Squashed commit of the following:

commit 7f2286cb6e36f90ca19f2830b341d34af513c9a3
Merge: e9f2e08b 9640752d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 11:55:46 2020 +0300

    Merge branch 'master' into fix/1813

commit e9f2e08b608ad14e5b327ab86d8faa66784bae44
Merge: ecee0977 f5a1f311
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 11:49:52 2020 +0300

    Merge branch 'master' into fix/1813

commit ecee0977ab5439d3be2a99447a771871f0340a2e
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 11:35:10 2020 +0300

    Capitalize category names

commit b4b47ce0177369fb4da5ad2e10a78b2d96bd81c6
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jul 2 18:11:40 2020 +0300

    - client: Fix client tracker source links
2020-07-03 12:01:03 +03:00
Artem Baskal
9640752d20 - client: Don't normalise disallowed domains
Close #1820

Squashed commit of the following:

commit 0c758ddcd738136b92e6f947a8068ecc59f7ec25
Merge: 15650db3 f5a1f311
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 11:22:00 2020 +0300

    Merge branch 'master' into fix/1820

commit 15650db35323009001fd427a74a312705b54ac86
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jun 29 12:01:51 2020 +0300

    '- client: Don't normalise disallowed domains'
2020-07-03 11:45:56 +03:00
Artem Baskal
f5a1f31103 - client: Display DomainCell popover
Close #1817

Squashed commit of the following:

commit 203d52e9b23013cb516765c3d41c288f8ce9d90c
Merge: 5c78d918 205680b7
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 11:15:28 2020 +0300

    Merge branch 'master' into fix/1817

commit 5c78d918ee2901ff138d5d06046e74ed00dc230d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jul 2 17:50:59 2020 +0300

    - client: Display DomainCell popover
2020-07-03 11:21:23 +03:00
Artem Baskal
205680b71b - client: Make language tag in HTML same as setting language
Close #1797

Squashed commit of the following:

commit b822a83cb05cc5ba92000cdb7d1c12629471bc57
Merge: e2fa24fb 72ce5f57
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jul 3 11:02:56 2020 +0300

    Merge branch 'master' into fix/1797

commit e2fa24fb9fa0c15f8411e186e90e0ffb1c705fb2
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jul 2 18:21:30 2020 +0300

    Extract helper

commit ba8473e7b16ab8b1abbee4b42a4ef2b0de8c136b
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jul 2 15:31:42 2020 +0300

    - client: Make language tag in HTML same as setting language
2020-07-03 11:14:54 +03:00
Simon Zolin
72ce5f57c1 - auth: show detailed error message if Bolt couldn't initialize its DB
Close #1846

Squashed commit of the following:

commit 34c612852b784d78191b37577324adeb0149e789
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jul 2 16:43:27 2020 +0300

    - auth: show detailed error message if Bolt couldn't initialize its DB
2020-07-02 16:52:29 +03:00
Simon Zolin
250b254c33 - home: when printing HTTP addresses to console, use all IP addresses
Close #1856

Squashed commit of the following:

commit 47ff99f147216bf28f1395847148f084b9dd4deb
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jul 2 14:27:03 2020 +0300

    - home: when printing HTTP addresses to console, use all IP addresses
2020-07-02 14:42:39 +03:00
Andrey Meshkov
da6cd57587 rollback dns 2020-06-29 20:37:25 +03:00
Andrey Meshkov
25a14e98ab add dns to docker run 2020-06-29 20:34:26 +03:00
Andrey Meshkov
da5467903e Fix #1433 2020-06-29 17:46:58 +03:00
Andrey Meshkov
4b2c33d12e Update translations 2020-06-29 17:24:16 +03:00
Simon Zolin
e38a1a5833 * use dnsproxy v0.29.1
Close #1777

Squashed commit of the following:

commit 5aab12162e9366ccf37bfe662f22bee59b8f98f5
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 29 12:07:34 2020 +0300

    * use dnsproxy v0.29.1
2020-06-29 14:03:12 +03:00
Simon Zolin
7a77dadab0 Merge: * SB/PC: limit the number of hashes in request to 4
Close #1697

* commit '0ee3505e1f0cc3df78651f2f9cb393c5ff3df26e':
  * SB/PC: limit the number of hashes in request to 4
2020-06-26 11:21:09 +03:00
Andrey Meshkov
4f295d41e8 Merge: - client: Query logs fix
* commit 'caf78ae3a084f1bf298a2a12940042e1645cad2b':
  minor
  Open tooltip on hover, show scroll on overflow y
  Replace tooltip component
  -client: Fix query log bugs
2020-06-24 00:11:59 +03:00
Andrey Meshkov
7d93457154 Merge : *(home): do not require root privileges on the first run
* commit '7b2cc51e35bfb725f02e91cb991ddd099b81ee0c':
  fix function comment
  *(home): do not require root privileges on the first run
2020-06-23 18:24:00 +03:00
Andrey Meshkov
7b2cc51e35 fix function comment 2020-06-23 18:04:26 +03:00
Andrey Meshkov
b43223d302 *(home): do not require root privileges on the first run
Instead of requiring root privileges, we now check if AdGuard Home can
bind to privileged ports. If it cannot, we suggest either running it
with root privileges or grant CAP_NET_BIND_SERVICE capability. Please
note, that on Windows we still require root access.

Closes: #1699
2020-06-23 18:02:28 +03:00
Andrey Meshkov
6693de9e8e Merge: + pass client Name and IP to dnsfilter
use urlfilter v0.11.0

Fix #1732
Fix #1761

* commit '890876cb0539d4916a21c0e0771a9d4e8322b9be':
  + pass client Name and IP to dnsfilter
2020-06-23 16:20:34 +03:00
Simon Zolin
890876cb05 + pass client Name and IP to dnsfilter
* use urlfilter v0.11.0
2020-06-23 14:36:26 +03:00
Simon Zolin
0ee3505e1f * SB/PC: limit the number of hashes in request to 4 2020-06-23 12:39:19 +03:00
Simon Zolin
49a92605b8 + dns: respond to PTR requests for internal IP addresses from DHCP
Close #1682

Squashed commit of the following:

commit 2fad3544bf8853b1f8f19ad8b7bc8a490c96e533
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 17:32:45 2020 +0300

    minor

commit 7c17992424702d95e6de91f30e8ae2dfcd8de257
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 16:09:34 2020 +0300

    build

commit 16a52e11a015a97d3cbf30362482a4abd052192b
Merge: 7b6a73c8 2c47053c
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 16:08:32 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1682-dhcp-resolve

commit 7b6a73c84b5cb9a073a9dfb7d7bdecd22e1e1318
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 22 16:01:34 2020 +0300

    tests

commit c2654abb2e5e7b7e3a04e4ddb8e1064b37613929
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 1 15:15:13 2020 +0300

    + dnsforward: respond to PTR requests for internal IP addresses

    {[IP] => "host"} <- DNSforward <-(leases)-- DHCP
2020-06-23 12:13:13 +03:00
ArtemBaskal
caf78ae3a0 Merge with master 2020-06-19 14:48:10 +03:00
ArtemBaskal
679b79a89d minor 2020-06-19 14:44:23 +03:00
Simon Zolin
2c47053cfe - autohosts: fix crash on startup if filesystem watcher couldn't be initialized
Close #1814

Squashed commit of the following:

commit ba17a5b3c61a8a5282beb0cca470e2302e83c0d6
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jun 19 10:08:44 2020 +0300

    - autohosts: fix crash on startup if filesystem watcher couldn't be initialized
2020-06-19 14:27:23 +03:00
Andrey Meshkov
aa7b3c33d5 Fix #1810
- client: Fix query log bugs

Squashed commit of the following:

commit 188bbad32a2af8a1867fc3ef91d81cda6aa94853
Merge: 15db9e9c ec6e0bea
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Jun 18 22:43:11 2020 +0300

    Merge branch 'master' into fix/1810

commit 15db9e9c1d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 18 19:01:10 2020 +0300

    Open tooltip on hover, show scroll on overflow y

commit 19c013378d
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 18 17:17:46 2020 +0300

    Replace tooltip component

commit 7e7103dc08
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 18 14:21:54 2020 +0300

    -client: Fix query log bugs
2020-06-18 22:53:02 +03:00
ArtemBaskal
15db9e9c1d Open tooltip on hover, show scroll on overflow y 2020-06-18 19:01:10 +03:00
ArtemBaskal
19c013378d Replace tooltip component 2020-06-18 17:17:46 +03:00
ArtemBaskal
7e7103dc08 -client: Fix query log bugs 2020-06-18 14:21:54 +03:00
Simon Zolin
ec6e0bea07 * openapi: describe top_* array entries in /stats
Squashed commit of the following:

commit d0b640cb36985c82f1020de99fba2201a1c54738
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jun 18 11:53:16 2020 +0300

    * openapi: describe top_* array entries in /stats
2020-06-18 13:49:52 +03:00
Andrey Meshkov
523aeb5c98 fix log table width 2020-06-18 00:53:39 +03:00
Artem Baskal
e39fe1b913 Merge: fix #1421
Full rework of the query log

Squashed commit of the following:

commit e8a72eb223551f17e637136713dae03accf8ab9e
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Jun 18 00:31:53 2020 +0300

    fix race in whois test

commit 801d28197f888fa21f83c9a0b49e3c9472c08513
Merge: 9d9787fd b1c951fb
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Jun 18 00:28:13 2020 +0300

    Merge branch 'master' into feature/1421

commit 9d9787fd79b17f76c7baed52c12ac462fd00a5e4
Merge: 4ce337ca 08e238ab
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Jun 18 00:27:32 2020 +0300

    Merge

commit 4ce337ca7aec163edf87a038bb25fb44e64f8613
Author: Andrey Meshkov <am@adguard.com>
Date:   Thu Jun 18 00:22:49 2020 +0300

    -(home): fix whois test

commit 08e238ab0e723b1e354f58245e9a8d5017b392c9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 18 00:13:41 2020 +0300

    Add comments

commit 5f108065952bcc25dce1c2eee3f9401d2641a6e9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 17 23:47:50 2020 +0300

    Make tooltip position absolute for touch

commit 4c30a583165e5d007d4b01b657de8751a7bd8c7b
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 17 20:39:44 2020 +0300

    Prevent scroll hide for touch devices

commit 62da97931f5921613762614717c62c77ddb6b8db
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 17 20:06:24 2020 +0300

    Review changes: ipad tooltip

commit 12dddcca8caca51c157b5d25dfa3ca03ba7f0c06
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 17 16:59:16 2020 +0300

    Add close tooltip event for ipad

commit 62191e41d5bf67317f9f1dc6c6af08cbabb4bf90
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 17 16:39:40 2020 +0300

    Add success toast on logs refresh

commit 2ebdd6a8124269d737c8060c3247aaf35d85cb8b
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 17 16:01:37 2020 +0300

    Fix pagination

commit 5820c92bacd93d05a3d66d42ee95f099e1c5d9e9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 17 11:31:15 2020 +0300

    Revert "Render table in chunks"

    This reverts commit cdfcd849ccddc1bc35591edac7904129431470c9.

commit cdfcd849ccddc1bc35591edac7904129431470c9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 16 18:42:18 2020 +0300

    Render table in chunks

commit cc8c5e64274bf6e806e2e8a4bf305af745c3ed2a
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 16 17:35:24 2020 +0300

    Add pagination button hover effect

commit f7e134091a1556784a5fea9d83c50353536126ef
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 16 16:28:00 2020 +0300

    Make loader position absolute

commit a7b887b57d903f1f7ac967b861b5cc677728efc4
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 16 15:42:20 2020 +0300

    Ignore clients find without params

commit ecb322fefd4a161d79f28d17fe27827ee91701e4
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 16 15:30:48 2020 +0300

    Styles changes

commit 9323ce3938bf04e1290eade09201ba0790a250c0
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 16 14:32:23 2020 +0300

    Review styles changes

commit e0faa04ba3643f01b2ca99524cdd52b0731725c7
Merge: 98576823 15e71435
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 16 12:08:45 2020 +0300

    Merge branch '1421-new-qlog-v2' into feature/1421

commit 9857682371e8d9a3a91933cfb58a26b3470675d9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jun 15 18:32:02 2020 +0300

    Fix response cell

... and 88 more commits
2020-06-18 00:36:19 +03:00
Andrey Meshkov
b1c951fb2c Merge: + new query logs API
* commit '59c4a2886a97143e3a36912ec895dc1a06be88cc':
  openapi
  If there are no more older entries, `"oldest":""` is returned.
  fix search by "whitelisted", "rewritten"
  doc
  fix whois test
  + "dot"
  openapi
  * minor
  + client_proto
  * openapi
  + new query logs API
2020-06-18 00:23:52 +03:00
Simon Zolin
4870da7f94 * auto-hosts: support '#' comments after ip and hosts
Close #1807

Squashed commit of the following:

commit 9d3e2809df056354bb6195abf8106616c1e214b1
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jun 17 19:23:15 2020 +0300

    improve

commit 9b8c7104560c9c80f848f15818d49a065a38e498
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jun 17 11:07:56 2020 +0300

    * auto-hosts: support '#' comments after ip and hosts
2020-06-17 19:36:35 +03:00
Simon Zolin
a5c0381c46 + dns: new settings for cache 2020-06-16 15:38:35 +03:00
Simon Zolin
ec6ca93acd * dns: disable cache with "cache_size: 0" setting
Close #1591

Squashed commit of the following:

commit 547a971f5c4f11c519dfabd52d42fa626abf931a
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jun 16 14:46:06 2020 +0300

    * dns: disable cache with "cache_size: 0" setting
2020-06-16 15:13:38 +03:00
Simon Zolin
59c4a2886a openapi 2020-06-16 12:12:32 +03:00
Simon Zolin
bbc4eda39e If there are no more older entries, "oldest":"" is returned. 2020-06-16 12:10:17 +03:00
Simon Zolin
15e714350c fix search by "whitelisted", "rewritten" 2020-06-16 11:47:26 +03:00
Simon Zolin
b6052a4cd1 doc 2020-06-16 11:14:04 +03:00
Andrey Meshkov
5a93c1fb59 Merge branch 'gumadozucia-master' 2020-06-15 00:49:09 +03:00
gumadozucia
973c609a85 Update README.md
Per client configuration was added in Pi-hole 5.0,
2020-06-14 16:37:07 +02:00
Simon Zolin
6a0194c7a1 fix whois test 2020-06-11 15:39:54 +03:00
Artem Baskal
d1472afb96 - client: Refactor Setup guide component: Merge pull request #633 in DNS/adguard-home from fix/1740 to master
Close #1740

Squashed commit of the following:

commit 13593ad7580a0ad5a4d5c0abcb4f67d01ddb944a
Merge: 8cdc68de 1356ac26
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 11 12:02:02 2020 +0300

    Merge branch 'master' into fix/1740

commit 8cdc68debab3f0668ec4aa5cf9b55ce40ddd4985
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 10 19:35:51 2020 +0300

    Update locales with link

commit 320d8d2f189dff594954b3f5964279410594ee29
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 3 16:40:36 2020 +0300

    Refactor Tabs

commit 98bdcdb5eb35448d38ed42aa08cec2fce9ac849e
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 3 14:01:55 2020 +0300

    Separate content from markup of dns privacy list

commit cee5e5c411d1e9a93a16eba9d78f2f9479d9e729
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed May 27 21:12:11 2020 +0300

    - client: Refactor Setup guide component
2020-06-11 12:07:46 +03:00
Simon Zolin
1356ac2633 - clients: fix incorrect info for clients from /etc/hosts
Close #1786

Squashed commit of the following:

commit fc662252be38f20c9afda46fcb578efa50c9baf2
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Jun 11 10:57:26 2020 +0300

    - clients: fix incorrect info for clients from /etc/hosts
2020-06-11 11:11:52 +03:00
Simon Zolin
cf087fb8ff - service: "stop" didn't work correctly
Close #1785

Squashed commit of the following:

commit 40eba3049ac339b4e2537b2fd598c2fb1c6e8cd0
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jun 10 19:43:14 2020 +0300

    - service: "stop" didn't work correctly
2020-06-11 10:24:43 +03:00
Artem Baskal
a79dda5566 - client: Add default mode in the DNS settings: Merge pull request #650 in DNS/adguard-home from fix/1770 to master
Close #1770

Squashed commit of the following:

commit c1f75ea643623af78de020bd1bc49aa5b66e25c4
Merge: a5df78ad a869ec4c
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 10 18:56:24 2020 +0300

    Merge branch 'master' into fix/1770

commit a5df78ad303305efcafcfa2a170ff567a3a06db5
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Wed Jun 10 12:50:50 2020 +0300

    Revert "Update locales"

    This reverts commit 4b2b4499dea12949c53bce4ceeed595c17df84c6.

commit 4b2b4499dea12949c53bce4ceeed595c17df84c6
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 9 19:56:34 2020 +0300

    Update locales

commit 790cff0db84b5905362d2e2702b2cbca5c3c90b0
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jun 5 17:56:01 2020 +0300

    Update Upstream component with new api, extract reduxForm HOC names in constant

commit 72de3d5a92cc33d5b234c837879fc6990291e07b
Merge: 92a4a6ae 501a4e06
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jun 5 15:55:39 2020 +0300

    Merge remote-tracking branch 'origin/update-dnsproxy' into fix/1770

commit 501a4e06ab350e46ff78656141d925de9f2e4996
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jun 5 12:47:13 2020 +0300

    openapi

commit 3930bd196572924f164ed011629356a0ac0ec631
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jun 5 12:21:32 2020 +0300

    * DNS API: new setting "upstream_mode"; remove "fastest_addr", "parallel_requests"

    * use dnsproxy v0.29.0

commit 92a4a6ae24793a2a9ca05ad3ef2078573fd4d059
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 4 18:53:42 2020 +0300

    - client: Add default mode in the DNS settings
2020-06-10 19:04:19 +03:00
Simon Zolin
a869ec4cbb * DNS API: new setting "upstream_mode"; remove "fastest_addr", "parallel_requests"
* use dnsproxy v0.29.0

Squashed commit of the following:

commit f18b7231f3f3f84446c0d837855af342f3c971b4
Merge: 501a4e06 dae275e6
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jun 10 15:24:15 2020 +0300

    Merge remote-tracking branch 'origin/master' into update-dnsproxy

commit 501a4e06ab350e46ff78656141d925de9f2e4996
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jun 5 12:47:13 2020 +0300

    openapi

commit 3930bd196572924f164ed011629356a0ac0ec631
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jun 5 12:21:32 2020 +0300

    * DNS API: new setting "upstream_mode"; remove "fastest_addr", "parallel_requests"

    * use dnsproxy v0.29.0
2020-06-10 15:33:23 +03:00
Simon Zolin
dae275e6f9 * log: set default LogMaxAge = 3 days
Squashed commit of the following:

commit 80a1ce12982679022f553cb8dc778d506b010fed
Merge: 4e01a5bd c842a68a
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jun 5 17:53:53 2020 +0300

    Merge remote-tracking branch 'origin/master' into log

commit 4e01a5bda625c034c9154aa3a1f94559b45260be
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri Jun 5 13:56:39 2020 +0300

    * log: set default LogMaxAge = 3 days
2020-06-05 17:58:42 +03:00
Artem Baskal
c842a68a1b - client: Fix beyond 24 hour time format for en locale: Merge pull request #651 in DNS/adguard-home from fix/1766 to master
Close #1766

Squashed commit of the following:

commit 691aa0e30e8435c81118cb5b8784a6902ed10f08
Merge: 67d62fa9 4a81abb9
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jun 5 13:17:46 2020 +0300

    Merge branch 'master' into fix/1766

commit 67d62fa9f8c9e1e7c7db714b85aa19e6b897a2d0
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jun 5 11:53:47 2020 +0300

    Fix jsdocs of helpers

commit 459e3cf8e185033d7e20f0b1d24c6e0146310017
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 4 20:45:17 2020 +0300

    - client: Fix beyond 24 hour time format for en locale
2020-06-05 13:28:13 +03:00
Artem Baskal
4a81abb922 + client: Move "Blocked services" to a separate page under "Filters" menu: Merge pull request #649 in DNS/adguard-home from feature/1744 to master
Close #1744

Squashed commit of the following:

commit 912a80b8ff42c927a97d33ccb3eebf8c3ca188d9
Merge: bb5a77ff 5ce98bd2
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri Jun 5 12:47:21 2020 +0300

    Merge branch 'master' into feature/1744

commit bb5a77ff6b66743bf23c9582c523280bdf9ef63a
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Thu Jun 4 18:07:26 2020 +0300

    + client: Move "Blocked services" to a separate page under "Filters" menu
2020-06-05 13:03:48 +03:00
Simon Zolin
5ce98bd2a4 Merge: + config: add new logging settings
Close #1763

* commit '0d343abec05b87e08f8a510fad8f969c8b8f1747':
  * minor
  + config: Added in lumberjack to handle rolling logs. Added more config properties around new log feature.
2020-06-05 12:30:16 +03:00
Simon Zolin
539ccb2bf0 Merge: + querylog,stats: anonymize client ip: /16
Close #1741

* commit '1b5fb97a023e79721e08a7ecedf1f2b36d7ebce6':
  + querylog,stats: anonymize client ip: /16
2020-06-03 19:17:50 +03:00
Simon Zolin
1b5fb97a02 + querylog,stats: anonymize client ip: /16 2020-06-03 19:08:11 +03:00
Simon Zolin
0d343abec0 * minor 2020-06-02 19:20:31 +03:00
DannyHinshaw
e23b79dda0 + config: Added in lumberjack to handle rolling logs. Added more config properties around new log feature.
Reset logger max file size config. Fix #1573.

Remove verbose from default config.
2020-06-02 19:18:37 +03:00
Artem Baskal
2ecd38544a - client: Hide version on inintial setup and login: Merge pull request #642 in DNS/adguard-home from fix/1748 to master
Close #1748

Squashed commit of the following:

commit 16721edf69eb3f5ad96253e0999b99c3aaeac822
Merge: 15e1867f eac1b809
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Tue Jun 2 13:37:57 2020 +0300

    Merge branch 'master' into fix/1748

commit 15e1867fdaee8d5c024d74ee2ef7416fec920341
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Mon Jun 1 13:54:15 2020 +0300

    - client: Hide version on inintial setup and login
2020-06-02 13:46:35 +03:00
Simon Zolin
eac1b80930 Merge: * blocked-services: Added 2 entries for YouTube and Amazon AWS
Close #1758

* commit 'bb016f07c6ae93dbe5708c818a87e1b991b81578':
  * blocked-services: Added 2 entries for YouTube and Amazon AWS
2020-06-01 15:26:21 +03:00
Simon Zolin
9a030aa99f - rewrites: fix invalid question in response
#1746

for a rule:

cname -> domain

with IP of 'domain' resolved by upstream

Squashed commit of the following:

commit fb3ad25ac8a7963a8fa6587cdc33e2fc35f79dfb
Merge: a6794989 67dacdf8
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 1 15:15:23 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1746-rewrites

commit a679498904a817011b55c58ee579e55f27fa0bc8
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Jun 1 10:42:16 2020 +0300

    test: check question

commit 7491e753c5eb6df54c9c050b0fa198c81dded2a0
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri May 29 18:22:32 2020 +0300

    test

commit 12cb2e194191ca489c9025b55f8571ae2dd7c33d
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Fri May 29 14:51:06 2020 +0300

    - rewrites: fix invalid question in response

    for a rule:

    cname -> domain

    with IP of 'domain' resolved by upstream
2020-06-01 15:23:08 +03:00
Imre Kristoffer Eilertsen
bb016f07c6 * blocked-services: Added 2 entries for YouTube and Amazon AWS 2020-06-01 12:03:54 +03:00
Artem Baskal
67dacdf8ae - client: Fix safari icon: Merge pull request #640 in DNS/adguard-home from fix/1751 to master
Close #1751

* commit '262bcd847f1468ca2f77000f4cd32a402e352414':
  - client: Fix safari icon
2020-05-29 18:59:33 +03:00
ArtemBaskal
262bcd847f - client: Fix safari icon 2020-05-29 18:40:58 +03:00
Artem Baskal
620f5c22c7 - client: fix/1754 - Merge pull request #639 in DNS/adguard-home from fix/1754 to master
Close #1754

* commit 'dddcbe77e29ff815e32913de4e5d99be98ab9934':
  -client: Fix "DNS rewrites" adding an item error
2020-05-29 17:09:15 +03:00
Artem Baskal
b8032801a2 - client: Submit setFiltersConfig action on if the values are changed: Merge pull request #637 in DNS/adguard-home from fix/1749 to master
Close #1749

Squashed commit of the following:

commit aaf4ba86429670ea8b0001325562c4a173be5b4a
Author: ArtemBaskal <a.baskal@adguard.com>
Date:   Fri May 29 13:29:44 2020 +0300

    - client: Submit setFiltersConfig action on if the values are changed
2020-05-29 16:08:01 +03:00
ArtemBaskal
dddcbe77e2 -client: Fix "DNS rewrites" adding an item error 2020-05-29 16:05:36 +03:00
Simon Zolin
bccb939346 + "dot" 2020-05-29 11:46:37 +03:00
Simon Zolin
78648649fe openapi 2020-05-29 11:19:31 +03:00
Simon Zolin
d971bb9957 * minor 2020-05-29 11:15:31 +03:00
Simon Zolin
0904eeffa8 + client_proto 2020-05-29 11:15:22 +03:00
Simon Zolin
0adbce5d38 * openapi 2020-05-28 17:58:56 +03:00
Simon Zolin
0500aa9591 + new query logs API
+ "upstream"
+ filteringStatusProcessed
+ ctDomainOrClient
remove ctQuestionType, ctDomain, ctClient
2020-05-28 17:14:50 +03:00
Tobias Messner
0a0c82d227 Update discord block for new domain
Discord now also uses discord.com as domain, this adds it to the blocked services list
2020-05-05 18:13:29 +02:00
197 changed files with 7767 additions and 3873 deletions

40
.dockerignore Normal file
View File

@@ -0,0 +1,40 @@
.DS_Store
/.git
/.github
/.vscode
.idea
/AdGuardHome
/AdGuardHome.exe
/AdGuardHome.yaml
/AdGuardHome.log
/data
/build
/dist
/client/node_modules
/.gitattributes
/.gitignore
/.goreleaser.yml
/changelog.config.js
/coverage.txt
/Dockerfile
/LICENSE.txt
/Makefile
/querylog.json
/querylog.json.1
/*.md
# Test output
dnsfilter/tests/top-1m.csv
dnsfilter/tests/dnsfilter.TestLotsOfRules*.pprof
# Snapcraft build temporary files
*.snap
launchpad_credentials
snapcraft_login
snapcraft.yaml.bak
# IntelliJ IDEA project files
*.iml
# Packr
*-packr.go

172
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,172 @@
name: build
env:
GO_VERSION: 1.14
NODE_VERSION: 13
on:
push:
branches:
- '*'
tags:
- v*
pull_request:
jobs:
test:
runs-on: ${{ matrix.os }}
env:
GO111MODULE: on
GOPROXY: https://goproxy.io
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macOS-latest
- windows-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
-
name: Set up Node
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
-
name: Set up Go modules cache
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }}
restore-keys: |
${{ runner.os }}-go-
-
name: Get npm cache directory
id: npm-cache
run: |
echo "::set-output name=dir::$(npm config get cache)"
-
name: Set up npm cache
uses: actions/cache@v2
with:
path: ${{ steps.npm-cache.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('client/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
-
name: Run make ci
shell: bash
run: |
make ci
-
name: Upload coverage
uses: codecov/codecov-action@v1
if: success() && matrix.os == 'ubuntu-latest'
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.txt
app:
runs-on: ubuntu-latest
needs: test
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
-
name: Set up Node
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
-
name: Set up Go modules cache
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }}
restore-keys: |
${{ runner.os }}-go-
-
name: Get npm cache directory
id: npm-cache
run: |
echo "::set-output name=dir::$(npm config get cache)"
-
name: Set up node_modules cache
uses: actions/cache@v2
with:
path: ${{ steps.npm-cache.outputs.dir }}
key: ${{ runner.os }}-node-${{ hashFiles('client/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
-
name: Set up Snapcraft
run: |
sudo apt-get -yq --no-install-suggests --no-install-recommends install snapcraft
-
name: Set up GoReleaser
run: |
curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | BINDIR="$(go env GOPATH)/bin" sh
-
name: Run snapshot build
run: |
make release
docker:
runs-on: ubuntu-latest
needs: test
steps:
-
name: Set up Docker Buildx
uses: crazy-max/ghaction-docker-buildx@v1
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Docker Buildx (build)
run: |
make docker-multi-arch
-
name: Clear
if: always() && startsWith(github.ref, 'refs/tags/v')
run: |
rm -f ${HOME}/.docker/config.json
notify:
needs: [app, docker]
# Secrets are not passed to workflows that are triggered by a pull request from a fork
if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
steps:
-
name: Conclusion
uses: technote-space/workflow-conclusion-action@v1
-
name: Send Slack notif
uses: 8398a7/action-slack@v3
with:
status: ${{ env.WORKFLOW_CONCLUSION }}
fields: repo,message,commit,author
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

47
.github/workflows/lint.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: golangci-lint
on:
push:
tags:
- v*
branches:
- '*'
pull_request:
jobs:
golangci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v1
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.27
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install modules
run: npm --prefix client ci
- name: Run ESLint
run: npm --prefix client run lint
notify:
needs: [golangci,eslint]
# Secrets are not passed to workflows that are triggered by a pull request from a fork
if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
steps:
-
name: Conclusion
uses: technote-space/workflow-conclusion-action@v1
-
name: Send Slack notif
uses: 8398a7/action-slack@v3
with:
status: ${{ env.WORKFLOW_CONCLUSION }}
fields: repo,message,commit,author
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

4
.gitignore vendored
View File

@@ -11,7 +11,6 @@
/client/node_modules/
/querylog.json
/querylog.json.1
/a_main-packr.go
coverage.txt
# Test output
@@ -26,3 +25,6 @@ snapcraft.yaml.bak
# IntelliJ IDEA project files
*.iml
# Packr
*-packr.go

View File

@@ -15,6 +15,9 @@ run:
- dnsfilter/rule_to_regexp.go
- util/pprof.go
- ".*_test.go"
- client/.*
- build/.*
- dist/.*
# all available settings of specific linters

View File

@@ -1,29 +0,0 @@
{
"Vendor": true,
"Test": true,
"Deadline": "2m",
"Sort": ["linter", "severity", "path", "line"],
"Exclude": [
".*generated.*",
"dnsfilter/rule_to_regexp.go"
],
"EnableGC": true,
"Linters": {
"nakedret": {
"Command": "nakedret",
"Pattern": "^(?P<path>.*?\\.go):(?P<line>\\d+)\\s*(?P<message>.*)$"
}
},
"WarnUnmatchedDirective": true,
"EnableAll": true,
"DisableAll": false,
"Disable": [
"maligned",
"goconst",
"vetshadow"
],
"Cyclo": 20,
"LineLength": 200
}

90
.goreleaser.yml Normal file
View File

@@ -0,0 +1,90 @@
project_name: AdGuardHome
env:
- GO111MODULE=on
- GOPROXY=https://goproxy.io
before:
hooks:
- go mod download
- go generate ./...
builds:
-
main: ./main.go
ldflags:
- -s -w -X main.version={{.Version}} -X main.channel={{.Env.CHANNEL}} -X main.goarm={{.Env.GOARM}}
env:
- CGO_ENABLED=0
goos:
- darwin
- linux
- freebsd
- windows
goarch:
- 386
- amd64
- arm
- arm64
- mips
- mipsle
- mips64
- mips64le
goarm:
- 5
- 6
- 7
gomips:
- softfloat
ignore:
- goos: freebsd
goarch: mips
- goos: freebsd
goarch: mipsle
archives:
-
# Archive name template.
# Defaults:
# - if format is `tar.gz`, `tar.xz`, `gz` or `zip`:
# - `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}`
# - if format is `binary`:
# - `{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}`
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}"
wrap_in_directory: "AdGuardHome"
format_overrides:
- goos: windows
format: zip
- goos: darwin
format: zip
files:
- LICENSE.txt
- README.md
snapcrafts:
-
name: adguard-home
base: core18
name_template: '{{ .ProjectName }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
summary: Network-wide ads & trackers blocking DNS server
description: |
AdGuard Home is a network-wide software for blocking ads & tracking. After
you set it up, it'll cover ALL your home devices, and you don't need any
client-side software for that.
It operates as a DNS server that re-routes tracking domains to a "black hole,"
thus preventing your devices from connecting to those servers. It's based
on software we use for our public AdGuard DNS servers -- both share a lot
of common code.
grade: stable
confinement: strict
publish: false
license: GPL-3.0
apps:
adguard-home:
command: AdGuardHome -w $SNAP_DATA --no-check-update
plugs: [ network-bind ]
daemon: simple
checksum:
name_template: 'checksums.txt'

View File

@@ -1,121 +0,0 @@
if: repo = AdguardTeam/AdGuardHome
language: go
sudo: false
go:
- 1.14.x
os:
- linux
- osx
- windows
before_install:
- |-
case $TRAVIS_OS_NAME in
linux | osx)
nvm install node
npm install -g npm
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(go env GOPATH)/bin v1.23.8
;;
windows)
# Using NVS for managing Node.js versions on Windows
NVS_HOME="C:\ProgramData\nvs"
git clone --single-branch https://github.com/jasongin/nvs $NVS_HOME
source $NVS_HOME/nvs.sh
nvs add latest
nvs use latest
;;
esac
install:
- |-
case $TRAVIS_OS_NAME in
linux | osx)
node --version
npm --version
npm --prefix client ci
;;
windows)
node --version
npm --version
nvs --version
npm --prefix client ci
;;
esac
cache:
directories:
- $HOME/.cache/go-build
- $HOME/gopath/pkg/mod
- $HOME/Library/Caches/go-build
script:
- |-
case $TRAVIS_OS_NAME in
linux | osx)
/bin/bash ci.sh
;;
windows)
npm --prefix client run build-prod
go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./...
;;
esac
after_success:
- |-
case $TRAVIS_OS_NAME in
linux)
bash <(curl -s https://codecov.io/bash)
;;
esac
notifications:
slack: performix:yXTihlSzsLFSZiqbXMNzvTSX
matrix:
include:
# Release build configuration
- if: repo = AdguardTeam/AdGuardHome
- name: release
go:
- 1.14.x
os:
- linux
script:
- node -v
- npm -v
# Prepare releases
- ./build_release.sh
- ls -l dist
deploy:
provider: releases
api_key: $GITHUB_TOKEN
file:
- dist/AdGuardHome_*
on:
repo: AdguardTeam/AdGuardHome
tags: true
draft: true
file_glob: true
skip_cleanup: true
# Docker build configuration
- if: repo = AdguardTeam/AdGuardHome
- name: docker
if: type != pull_request AND (branch = master OR tag IS present) AND repo = AdguardTeam/AdGuardHome
go:
- 1.14.x
os:
- linux
services:
- docker
before_script:
- nvm install node
- npm install -g npm
script:
- docker login -u="$DOCKER_USER" -p="$DOCKER_PASSWORD"
- ./build_docker.sh
after_script:
- docker images

View File

@@ -893,8 +893,10 @@ Response:
"edns_cs_enabled": true | false,
"dnssec_enabled": true | false
"disable_ipv6": true | false,
"fastest_addr": true | false, // use Fastest Address algorithm
"parallel_requests": true | false, // send DNS requests to all upstream servers at once
"upstream_mode": "" | "parallel" | "fastest_addr"
"cache_size": 1234, // in bytes
"cache_ttl_min": 1234, // in seconds
"cache_ttl_max": 1234, // in seconds
}
@@ -916,8 +918,10 @@ Request:
"edns_cs_enabled": true | false,
"dnssec_enabled": true | false
"disable_ipv6": true | false,
"fastest_addr": true | false, // use Fastest Address algorithm
"parallel_requests": true | false, // send DNS requests to all upstream servers at once
"upstream_mode": "" | "parallel" | "fastest_addr"
"cache_size": 1234, // in bytes
"cache_ttl_min": 1234, // in seconds
"cache_ttl_max": 1234, // in seconds
}
Response:
@@ -982,6 +986,110 @@ Response:
This section allows the administrator to easily configure custom DNS response for a specific domain name.
A, AAAA and CNAME records are supported.
Syntax:
key -> value
where `key` is a host name or a wild card that matches Question in DNS request
and `value` is either:
* IPv4 address: use this IP in A response
* IPv6 address: use this IP in AAAA response
* canonical name: add CNAME record
* "<key>": CNAME exception - pass request to upstream
* "A": A exception - pass A request to upstream
* "AAAA": AAAA exception - pass AAAA request to upstream
#### Example: A record
host.com -> 1.2.3.4
Response:
A:
A = 1.2.3.4
AAAA:
<empty>
#### Example: AAAA record
host.com -> ::1
Response:
A:
<empty>
AAAA:
AAAA = ::1
#### Example: CNAME record
sub.host.com -> host.com
Response:
A:
CNAME = host.com
A = <IPv4 address of host.com>
AAAA:
CNAME = host.com
AAAA = <IPv6 address of host.com>
#### Example: CNAME+A records
sub.host.com -> host.com
host.com -> 1.2.3.4
Response:
A:
CNAME = host.com
A = 1.2.3.4
AAAA:
CNAME = host.com
#### Example: Wildcard CNAME+A record with CNAME exception
*.host.com -> 1.2.3.4
pass.host.com -> pass.host.com
Response to `my.host.com`:
A:
A = 1.2.3.4
AAAA:
<empty>
Response to `pass.host.com`:
A:
A = <IPv4 address of pass.host.com>
AAAA:
AAAA = <IPv6 address of pass.host.com>
#### Example: A record with AAAA exception
host.com -> 1.2.3.4
host.com -> AAAA
Response:
A:
A = 1.2.3.4
AAAA:
AAAA = <IPv6 address of host.com>
#### Example: pass A only
host.com -> A
Response:
A:
A = <IPv4 address of host.com>
AAAA:
<empty>
### API: List rewrite entries
@@ -1200,8 +1308,9 @@ When a new DNS request is received and processed, we store information about thi
"QH":"...", // target host name without the last dot
"QT":"...", // question type
"QC":"...", // question class
"Answer":"...",
"OrigAnswer":"...",
"CP":"" | "doh", // client connection protocol
"Answer":"base64 data",
"OrigAnswer":"base64 data",
"Result":{
"IsFiltered":true,
"Reason":3,
@@ -1234,16 +1343,28 @@ Request:
GET /control/querylog
?older_than=2006-01-02T15:04:05.999999999Z07:00
&filter_domain=...
&filter_client=...
&filter_question_type=A | AAAA
&filter_response_status= | filtered
&search=...
&response_status="..."
`older_than` setting is used for paging. UI uses an empty value for `older_than` on the first request and gets the latest log entries. To get the older entries, UI sets `older_than` to the `oldest` value from the server's response.
`older_than` setting is used for paging. UI uses an empty value for `older_than` on the first request and gets the latest log entries. To get the older entries, UI sets `older_than` to the `oldest` value from the server's response.
If "filter" settings are set, server returns only entries that match the specified request.
If search settings are set, server returns only entries that match the specified request.
For `filter.domain` and `filter.client` the server matches substrings by default: `adguard.com` matches `www.adguard.com`. Strict matching can be enabled by enclosing the value in double quotes: `"adguard.com"` matches `adguard.com` but doesn't match `www.adguard.com`.
`search`:
match by domain name or client IP address.
The server matches substrings by default: e.g. `adguard.com` matches `www.adguard.com`.
Strict matching can be enabled by enclosing the value in double quotes: e.g. `"adguard.com"` matches `adguard.com` but doesn't match `www.adguard.com`.
`response_status`:
* all
* filtered - all kinds of filtering
* blocked - blocked or blocked service
* blocked_safebrowsing - blocked by safebrowsing
* blocked_parental - blocked by parental control
* whitelisted - whitelisted
* rewritten - all kinds of rewrites
* safe_search - enforced safe search
* processed - not blocked, not white-listed entries
Response:
@@ -1266,8 +1387,10 @@ Response:
}
...
],
"upstream":"...", // Upstream URL starting with tcp://, tls://, https://, or with an IP address
"answer_dnssec": true,
"client":"127.0.0.1",
"client_proto": "" (plain) | "doh" | "dot",
"elapsedMs":"0.098403",
"filterId":1,
"question":{
@@ -1287,6 +1410,8 @@ Response:
The most recent entries are at the top of list.
If there are no more older entries, `"oldest":""` is returned.
### API: Set querylog parameters

78
Dockerfile Normal file
View File

@@ -0,0 +1,78 @@
FROM --platform=${BUILDPLATFORM:-linux/amd64} tonistiigi/xx:golang AS xgo
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.14-alpine as builder
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION=dev
ARG CHANNEL=release
ENV CGO_ENABLED 0
ENV GO111MODULE on
ENV GOPROXY https://goproxy.io
COPY --from=xgo / /
RUN go env
RUN apk --update --no-cache add \
build-base \
gcc \
git \
npm \
&& rm -rf /tmp/* /var/cache/apk/*
WORKDIR /app
COPY . ./
# Prepare the client code
RUN npm --prefix client ci && npm --prefix client run build-prod
# Download go dependencies
RUN go mod download
RUN go generate ./...
# It's important to place TARGET* arguments here to avoid running npm and go mod download for every platform
ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH
RUN go build -ldflags="-s -w -X main.version=${VERSION} -X main.channel=${CHANNEL} -X main.goarm=${GOARM}"
FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:latest
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION
ARG CHANNEL
LABEL maintainer="AdGuard Team <devteam@adguard.com>" \
org.opencontainers.image.created=$BUILD_DATE \
org.opencontainers.image.url="https://adguard.com/adguard-home.html" \
org.opencontainers.image.source="https://github.com/AdguardTeam/AdGuardHome" \
org.opencontainers.image.version=$VERSION \
org.opencontainers.image.revision=$VCS_REF \
org.opencontainers.image.vendor="AdGuard" \
org.opencontainers.image.title="AdGuard Home" \
org.opencontainers.image.description="Network-wide ads & trackers blocking DNS server" \
org.opencontainers.image.licenses="GPL-3.0"
RUN apk --update --no-cache add \
ca-certificates \
libcap \
libressl \
tzdata \
&& rm -rf /tmp/* /var/cache/apk/*
COPY --from=builder --chown=nobody:nogroup /app/AdGuardHome /opt/adguardhome/AdGuardHome
COPY --from=builder --chown=nobody:nogroup /usr/local/go/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip
RUN /opt/adguardhome/AdGuardHome --version \
&& mkdir -p /opt/adguardhome/conf /opt/adguardhome/work \
&& chown -R nobody: /opt/adguardhome \
&& setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome
EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 853/tcp 3000/tcp
WORKDIR /opt/adguardhome/work
VOLUME ["/opt/adguardhome/conf", "/opt/adguardhome/work"]
ENTRYPOINT ["/opt/adguardhome/AdGuardHome"]
CMD ["-h", "0.0.0.0", "-c", "/opt/adguardhome/conf/AdGuardHome.yaml", "-w", "/opt/adguardhome/work", "--no-check-update"]

View File

@@ -1,23 +0,0 @@
FROM alpine:latest
LABEL maintainer="AdGuard Team <devteam@adguard.com>"
# Update CA certs
RUN apk --no-cache --update add ca-certificates libcap && \
rm -rf /var/cache/apk/* && \
mkdir -p /opt/adguardhome/conf /opt/adguardhome/work && \
chown -R nobody: /opt/adguardhome
COPY --chown=nobody:nogroup ./AdGuardHome /opt/adguardhome/AdGuardHome
RUN setcap 'cap_net_bind_service=+eip' /opt/adguardhome/AdGuardHome
EXPOSE 53/tcp 53/udp 67/udp 68/udp 80/tcp 443/tcp 853/tcp 3000/tcp
VOLUME ["/opt/adguardhome/conf", "/opt/adguardhome/work"]
WORKDIR /opt/adguardhome/work
#USER nobody
ENTRYPOINT ["/opt/adguardhome/AdGuardHome"]
CMD ["-h", "0.0.0.0", "-c", "/opt/adguardhome/conf/AdGuardHome.yaml", "-w", "/opt/adguardhome/work", "--no-check-update"]

241
Makefile
View File

@@ -1,43 +1,226 @@
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
NATIVE_GOOS = $(shell unset GOOS; go env GOOS)
NATIVE_GOARCH = $(shell unset GOARCH; go env GOARCH)
#
# Available targets
#
# * build -- builds AdGuardHome for the current platform
# * client -- builds client-side code of AdGuard Home
# * client-watch -- builds client-side code of AdGuard Home and watches for changes there
# * docker -- builds a docker image for the current platform
# * clean -- clean everything created by previous builds
# * lint -- run all linters
# * test -- run all unit-tests
# * dependencies -- installs dependencies (go and npm modules)
# * ci -- installs dependencies, runs linters and tests, intended to be used by CI/CD
#
# Building releases:
#
# * release -- builds AdGuard Home distros. CHANNEL must be specified (edge, release or beta).
# * docker-multi-arch -- builds a multi-arch image. If you want it to be pushed to docker hub,
# you must specify:
# * DOCKER_IMAGE_NAME - adguard/adguard-home
# * DOCKER_OUTPUT - type=image,name=adguard/adguard-home,push=true
GOPATH := $(shell go env GOPATH)
JSFILES = $(shell find client -path client/node_modules -prune -o -type f -name '*.js')
STATIC = build/static/index.html
CHANNEL ?= release
DOCKER_IMAGE_DEV_NAME=adguardhome-dev
DOCKERFILE=packaging/docker/Dockerfile
DOCKERFILE_HUB=packaging/docker/Dockerfile.travis
PWD := $(shell pwd)
TARGET=AdGuardHome
BASE_URL="https://static.adguard.com/adguardhome/$(CHANNEL)"
.PHONY: all build clean
# See release target
DIST_DIR=dist
# Update channel. Can be release, beta or edge. Uses edge by default.
CHANNEL ?= edge
# Validate channel
ifneq ($(CHANNEL),relese)
ifneq ($(CHANNEL),beta)
ifneq ($(CHANNEL),edge)
$(error CHANNEL value is not valid. Valid values are release,beta or edge)
endif
endif
endif
# goreleaser command depends on the $CHANNEL
GORELEASER_COMMAND=goreleaser release --rm-dist --skip-publish --snapshot
ifneq ($(CHANNEL),edge)
# If this is not an "edge" build, use normal release command
GORELEASER_COMMAND=goreleaser release --rm-dist --skip-publish
endif
# Version properties
COMMIT=$(shell git rev-parse --short HEAD)
TAG_NAME=$(shell git describe --abbrev=0)
RELEASE_VERSION=$(TAG_NAME)
SNAPSHOT_VERSION=$(RELEASE_VERSION)-SNAPSHOT-$(COMMIT)
# Set proper version
VERSION=
ifeq ($(TAG_NAME),$(shell git describe --abbrev=4))
VERSION=$(RELEASE_VERSION)
else
VERSION=$(SNAPSHOT_VERSION)
endif
# Docker target parameters
DOCKER_IMAGE_NAME ?= adguardhome-dev
DOCKER_IMAGE_FULL_NAME = $(DOCKER_IMAGE_NAME):$(VERSION)
DOCKER_PLATFORMS=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/386,linux/ppc64le
DOCKER_OUTPUT ?= type=image,name=$(DOCKER_IMAGE_NAME),push=false
BUILD_DATE=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')
# Docker tags (can be redefined)
DOCKER_TAGS ?=
ifndef DOCKER_TAGS
ifeq ($(CHANNEL),release)
DOCKER_TAGS := --tag $(DOCKER_IMAGE_NAME):latest
endif
ifeq ($(CHANNEL),beta)
DOCKER_TAGS := --tag $(DOCKER_IMAGE_NAME):beta
endif
ifeq ($(CHANNEL),edge)
# Don't set the version tag when pushing to "edge"
DOCKER_IMAGE_FULL_NAME := $(DOCKER_IMAGE_NAME):edge
# DOCKER_TAGS := --tag $(DOCKER_IMAGE_NAME):edge
endif
endif
# Validate docker build arguments
ifndef DOCKER_IMAGE_NAME
$(error DOCKER_IMAGE_NAME value is not set)
endif
.PHONY: all build client client-watch docker lint test dependencies clean release docker-multi-arch
all: build
build: $(TARGET)
client/node_modules: client/package.json client/package-lock.json
npm --prefix client ci
touch client/node_modules
$(STATIC): $(JSFILES) client/node_modules
npm --prefix client run build-prod
$(TARGET): $(STATIC) *.go home/*.go dhcpd/*.go dnsfilter/*.go dnsforward/*.go
GOOS=$(NATIVE_GOOS) GOARCH=$(NATIVE_GOARCH) GO111MODULE=off go get -v github.com/gobuffalo/packr/...
PATH=$(GOPATH)/bin:$(PATH) packr -z
CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=$(GIT_VERSION) -X main.channel=$(CHANNEL) -X main.goarm=$(GOARM)" -asmflags="-trimpath=$(PWD)" -gcflags="-trimpath=$(PWD)"
build: dependencies client
go generate ./...
CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=$(VERSION) -X main.channel=$(CHANNEL) -X main.goarm=$(GOARM)"
PATH=$(GOPATH)/bin:$(PATH) packr clean
client:
npm --prefix client run build-prod
client-watch:
npm --prefix client run watch
docker:
docker build -t "$(DOCKER_IMAGE_DEV_NAME)" -f "$(DOCKERFILE)" .
DOCKER_CLI_EXPERIMENTAL=enabled \
docker buildx build \
--build-arg VERSION=$(VERSION) \
--build-arg CHANNEL=$(CHANNEL) \
--build-arg VCS_REF=$(COMMIT) \
--build-arg BUILD_DATE=$(BUILD_DATE) \
$(DOCKER_TAGS) \
--load \
-t "$(DOCKER_IMAGE_NAME)" -f ./Dockerfile .
@echo Now you can run the docker image:
@echo docker run --name "$(DOCKER_IMAGE_DEV_NAME)" -p 53:53/tcp -p 53:53/udp -p 80:80/tcp -p 443:443/tcp -p 853:853/tcp -p 3000:3000/tcp $(DOCKER_IMAGE_DEV_NAME)
@echo docker run --name "adguard-home" -p 53:53/tcp -p 53:53/udp -p 80:80/tcp -p 443:443/tcp -p 853:853/tcp -p 3000:3000/tcp $(DOCKER_IMAGE_NAME)
lint:
@echo Running linters
golangci-lint run ./...
npm --prefix client run lint
test:
@echo Running unit-tests
go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./...
ci: dependencies client test
dependencies:
npm --prefix client ci
go mod download
clean:
$(MAKE) cleanfast
# make build output
rm -f AdGuardHome
rm -f AdGuardHome.exe
# tests output
rm -rf data
rm -f coverage.txt
# static build output
rm -rf build
# dist folder
rm -rf $(DIST_DIR)
# client deps
rm -rf client/node_modules
# packr-generated files
PATH=$(GOPATH)/bin:$(PATH) packr clean || true
cleanfast:
rm -f $(TARGET)
docker-multi-arch:
DOCKER_CLI_EXPERIMENTAL=enabled \
docker buildx build \
--platform $(DOCKER_PLATFORMS) \
--build-arg VERSION=$(VERSION) \
--build-arg CHANNEL=$(CHANNEL) \
--build-arg VCS_REF=$(COMMIT) \
--build-arg BUILD_DATE=$(BUILD_DATE) \
$(DOCKER_TAGS) \
--output "$(DOCKER_OUTPUT)" \
-t "$(DOCKER_IMAGE_FULL_NAME)" -f ./Dockerfile .
@echo If the image was pushed to the registry, you can now run it:
@echo docker run --name "adguard-home" -p 53:53/tcp -p 53:53/udp -p 80:80/tcp -p 443:443/tcp -p 853:853/tcp -p 3000:3000/tcp $(DOCKER_IMAGE_NAME)
release: dependencies client
@echo Starting release build: version $(VERSION), channel $(CHANNEL)
CHANNEL=$(CHANNEL) $(GORELEASER_COMMAND)
$(call write_version_file,$(VERSION))
PATH=$(GOPATH)/bin:$(PATH) packr clean
define write_version_file
$(eval version := $(1))
@echo Writing version file: $(version)
# Variables for CI
rm -f $(DIST_DIR)/version.txt
echo "version=$(version)" > $(DIST_DIR)/version.txt
# Prepare the version.json file
rm -f $(DIST_DIR)/version.json
echo "{" >> $(DIST_DIR)/version.json
echo " \"version\": \"$(version)\"," >> $(DIST_DIR)/version.json
echo " \"announcement\": \"AdGuard Home $(version) is now available!\"," >> $(DIST_DIR)/version.json
echo " \"announcement_url\": \"https://github.com/AdguardTeam/AdGuardHome/releases\"," >> $(DIST_DIR)/version.json
echo " \"selfupdate_min_version\": \"v0.0\"," >> $(DIST_DIR)/version.json
# Windows builds
echo " \"download_windows_amd64\": \"$(BASE_URL)/AdGuardHome_windows_amd64.zip\"," >> $(DIST_DIR)/version.json
echo " \"download_windows_386\": \"$(BASE_URL)/AdGuardHome_windows_386.zip\"," >> $(DIST_DIR)/version.json
# MacOS builds
echo " \"download_darwin_amd64\": \"$(BASE_URL)/AdGuardHome_darwin_amd64.zip\"," >> $(DIST_DIR)/version.json
echo " \"download_darwin_386\": \"$(BASE_URL)/AdGuardHome_darwin_386.zip\"," >> $(DIST_DIR)/version.json
# Linux
echo " \"download_linux_amd64\": \"$(BASE_URL)/AdGuardHome_linux_amd64.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_386\": \"$(BASE_URL)/AdGuardHome_linux_386.tar.gz\"," >> $(DIST_DIR)/version.json
# Linux, all kinds of ARM
echo " \"download_linux_arm\": \"$(BASE_URL)/AdGuardHome_linux_armv6.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_armv5\": \"$(BASE_URL)/AdGuardHome_linux_armv5.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_armv6\": \"$(BASE_URL)/AdGuardHome_linux_armv6.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_armv7\": \"$(BASE_URL)/AdGuardHome_linux_armv7.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_arm64\": \"$(BASE_URL)/AdGuardHome_linux_arm64.tar.gz\"," >> $(DIST_DIR)/version.json
# Linux, MIPS
echo " \"download_linux_mips\": \"$(BASE_URL)/AdGuardHome_linux_mips_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_mipsle\": \"$(BASE_URL)/AdGuardHome_linux_mipsle_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_mips64\": \"$(BASE_URL)/AdGuardHome_linux_mips64_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_linux_mips64le\": \"$(BASE_URL)/AdGuardHome_linux_mips64le_softfloat.tar.gz\"," >> $(DIST_DIR)/version.json
# FreeBSD
echo " \"download_freebsd_386\": \"$(BASE_URL)/AdGuardHome_freebsd_386.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_freebsd_amd64\": \"$(BASE_URL)/AdGuardHome_freebsd_amd64.tar.gz\"," >> $(DIST_DIR)/version.json
# FreeBSD, all kinds of ARM
echo " \"download_freebsd_arm\": \"$(BASE_URL)/AdGuardHome_freebsd_armv6.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_freebsd_armv5\": \"$(BASE_URL)/AdGuardHome_freebsd_armv5.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_freebsd_armv6\": \"$(BASE_URL)/AdGuardHome_freebsd_armv6.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_freebsd_armv7\": \"$(BASE_URL)/AdGuardHome_freebsd_armv7.tar.gz\"," >> $(DIST_DIR)/version.json
echo " \"download_freebsd_arm64\": \"$(BASE_URL)/AdGuardHome_freebsd_arm64.tar.gz\"" >> $(DIST_DIR)/version.json
# Finish
echo "}" >> $(DIST_DIR)/version.json
endef

124
README.md
View File

@@ -14,9 +14,6 @@
<a href="https://twitter.com/AdGuard">Twitter</a> |
<a href="https://t.me/adguard_en">Telegram</a>
<br /><br />
<a href="https://travis-ci.com/AdguardTeam/AdGuardHome">
<img src="https://travis-ci.com/AdguardTeam/AdGuardHome.svg" alt="Build status" />
</a>
<a href="https://codecov.io/github/AdguardTeam/AdGuardHome?branch=master">
<img src="https://img.shields.io/codecov/c/github/AdguardTeam/AdGuardHome/master.svg" alt="Code Coverage" />
</a>
@@ -63,6 +60,7 @@ It operates as a DNS server that re-routes tracking domains to a "black hole," t
* [Test unstable versions](#test-unstable-versions)
* [Reporting issues](#reporting-issues)
* [Help with translations](#translate)
* [Other](#help-other)
* [Projects that use AdGuardHome](#uses)
* [Acknowledgments](#acknowledgments)
@@ -121,10 +119,10 @@ AdGuard Home provides a lot of features out-of-the-box with no need to install a
| Encrypted DNS upstream servers (DNS-over-HTTPS, DNS-over-TLS, DNSCrypt) | ✅ | ❌ (requires additional software) |
| Cross-platform | ✅ | ❌ (not natively, only via Docker) |
| Running as a DNS-over-HTTPS or DNS-over-TLS server | ✅ | ❌ (requires additional software) |
| Blocking phishing and malware domains | ✅ | ❌ |
| Blocking phishing and malware domains | ✅ | ❌ (requires non-default blocklists) |
| Parental control (blocking adult domains) | ✅ | ❌ |
| Force Safe search on search engines | ✅ | ❌ |
| Per-client (device) configuration | ✅ | |
| Per-client (device) configuration | ✅ | |
| Access settings (choose who can use AGH DNS) | ✅ | ❌ |
<a id="comparison-adblock"></a>
@@ -132,24 +130,31 @@ AdGuard Home provides a lot of features out-of-the-box with no need to install a
It depends.
"DNS sinkholing" is capable of blocking a big percentage of ads, but it lacks flexibility and power of traditional ad blockers. You can get a good impression about the difference between these methods by reading [this article](https://adguard.com/en/blog/adguard-vs-adaway-dns66/). It compares AdGuard for Android (a traditional ad blocker) to hosts-level ad blockers (which are almost identical to DNS-based blockers in their capabilities). However, this level of protection is enough for some users. Additionally, using a DNS-based blocker can help to block ads, tracking and analytics requests on other types of devices, such as SmartTVs, smart speakers or other kinds of IoT devices (on which you can't install tradtional ad blockers).
"DNS sinkholing" is capable of blocking a big percentage of ads, but it lacks flexibility and power of traditional ad blockers. You can get a good impression about the difference between these methods by reading [this article](https://adguard.com/en/blog/adguard-vs-adaway-dns66/). It compares AdGuard for Android (a traditional ad blocker) to hosts-level ad blockers (which are almost identical to DNS-based blockers in their capabilities).
However, this level of protection is enough for some users. Additionally, using a DNS-based blocker can help to block ads, tracking and analytics requests on other types of devices, such as SmartTVs, smart speakers or other kinds of IoT devices (on which you can't install tradtional ad blockers).
**Known limitations**
Here are some examples of what cannot be blocked by a DNS-level blocker:
* YouTube, Twitch ads
* Facebook, Twitter, Instagram sponsored posts
Essentially, any advertising that shares a domain with content cannot be blocked by a DNS-level blocker.
Is there a chance to handle this in the future? DNS will never be enough to do this. Our only option is to use a content blocking proxy like what we do in the standalone AdGuard applications. We're [going to bring](https://github.com/AdguardTeam/AdGuardHome/issues/1228) this feature support to AdGuard Home in the future. Unfortunately, even in this case, there still will be cases when this won't be enough or would require quite complicated configuration.
<a id="how-to-build"></a>
## How to build from source
### Prerequisites
You will need:
You will need this to build AdGuard Home:
* [go](https://golang.org/dl/) v1.14 or later.
* [node.js](https://nodejs.org/en/download/) v10 or later.
You can either install them via the provided links or use [brew.sh](https://brew.sh/) if you're on Mac:
```bash
brew install go node
```
### Building
Open Terminal and execute these commands:
@@ -160,15 +165,38 @@ cd AdGuardHome
make
```
#### (For devs) Upload translations
```
node upload.js
```
Check the [`Makefile`](https://github.com/AdguardTeam/AdGuardHome/blob/master/Makefile) to learn about other commands.
#### (For devs) Download translations
```
node download.js
```
#### Preparing release
You'll need this to prepare a release build:
* [goreleaser](https://goreleaser.com/)
* [snapcraft](https://snapcraft.io/)
Commands:
* `make release` - builds a snapshot build (CHANNEL=edge)
* `CHANNEL=beta make release` - builds beta version, tag is mandatory.
* `CHANNEL=release make release` - builds release version, tag is mandatory.
#### Docker image
* Run `make docker` to build the Docker image locally.
* Run `make docker-multi-arch` to build the multi-arch Docker image (the one that we publish to Docker Hub).
Please note, that we're using [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx/) to build our official image.
You may need to prepare before using these builds:
* (Linux-only) Install Qemu: `docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes`
* Prepare builder: `docker buildx create --name buildx-builder --driver docker-container --use`
### Resources that we update periodically
* `scripts/translations`
* `scripts/whotracksme`
<a id="contributing"></a>
## Contributing
@@ -178,26 +206,41 @@ You are welcome to fork this repository, make your changes and submit a pull req
<a id="test-unstable-versions"></a>
### Test unstable versions
There are two update channels that you can use:
* `beta` - beta version of AdGuard Home. More or less stable versions.
* `edge` - the newest version of AdGuard Home. New updates are pushed to this channel daily and it is the closest to the master branch you can get.
There are three options how you can install an unstable version:
1. [Snap Store](https://snapcraft.io/adguard-home) -- look for "beta" and "edge" channels there.
2. [Docker Hub](https://hub.docker.com/r/adguard/adguardhome) -- look for "beta" and "edge" tags there.
3. Standalone builds. Look for the available builds below.
There are three options how you can install an unstable version.
1. You can either install a beta version of AdGuard Home which we update periodically.
2. You can use the Docker image from the `edge` tag, which is synced with the repo master branch.
3. You can install AdGuard Home from `beta` or `edge` channels on the Snap Store.
* Beta builds
* [Raspberry Pi (32-bit ARMv6)](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm.tar.gz)
* [MacOS](https://static.adguard.com/adguardhome/beta/AdGuardHome_MacOS.zip)
* [Windows 64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_Windows_amd64.zip)
* [Windows 32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_Windows_386.zip)
* [Linux 64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_amd64.tar.gz)
* [Linux 32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_386.tar.gz)
* [FreeBSD 64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_amd64.tar.gz)
* [Linux 64-bit ARM](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz)
* [Linux 32-bit ARMv5](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv5.tar.gz)
* [MIPS](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips.tar.gz)
* [MIPSLE](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mipsle.tar.gz)
* [Docker Hub](https://hub.docker.com/r/adguard/adguardhome)
* [Snap Store](https://snapcraft.io/adguard-home)
* Beta channel builds
* Linux: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_386.tar.gz)
* Linux ARM: [32-bit ARMv6](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv6.tar.gz) (recommended for Rapsberry Pi), [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv5.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_armv7.tar.gz)
* Linux MIPS: [32-bit MIPS](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips_softfloat.tar.gz), [32-bit MIPSLE](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mipsle_softfloat.tar.gz), [64-bit MIPS](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips64_softfloat.tar.gz), [64-bit MIPSLE](https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_mips64le_softfloat.tar.gz)
* Windows: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_windows_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_windows_386.zip)
* MacOS: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_darwin_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_darwin_386.zip)
* FreeBSD: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_386.tar.gz)
* FreeBSD ARM: [64-bit](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_armv5.tar.gz), [32-bit ARMv6](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_armv6.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/beta/AdGuardHome_freebsd_armv7.tar.gz)
* Edge channel builds
* Linux: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_386.tar.gz)
* Linux ARM: [32-bit ARMv6](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_armv6.tar.gz) (recommended for Rapsberry Pi), [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_armv5.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_armv7.tar.gz)
* Linux MIPS: [32-bit MIPS](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mips_softfloat.tar.gz), [32-bit MIPSLE](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mipsle_softfloat.tar.gz), [64-bit MIPS](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mips64_softfloat.tar.gz), [64-bit MIPSLE](https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_mips64le_softfloat.tar.gz)
* Windows: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_windows_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_windows_386.zip)
* MacOS: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_darwin_amd64.zip), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_darwin_386.zip)
* FreeBSD: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_amd64.tar.gz), [32-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_386.tar.gz)
* FreeBSD ARM: [64-bit](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_arm64.tar.gz), [32-bit ARMv5](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_armv5.tar.gz), [32-bit ARMv6](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_armv6.tar.gz), [32-bit ARMv7](https://static.adguard.com/adguardhome/edge/AdGuardHome_freebsd_armv7.tar.gz)
<a id="reporting-issues"></a>
### Report issues
@@ -211,6 +254,15 @@ If you want to help with AdGuard Home translations, please learn more about tran
Here is a link to AdGuard Home project: https://crowdin.com/project/adguard-applications/en#/adguard-home
<a id="help-other"></a>
### Other
Here's what you can also do to contribute:
1. [Look for issues](https://github.com/AdguardTeam/AdGuardHome/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+) marked as "help wanted".
2. Actualize the list of *Blocked services*. It it can be found in [dnsfilter/blocked_services.go](https://github.com/AdguardTeam/AdGuardHome/blob/master/dnsfilter/blocked_services.go).
3. Actualize the list of known *trackers*. It it can be found in [client/src/helpers/trackers/adguard.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/trackers/adguard.json).
4. Actualize the list of vetted *blocklists*. It it can be found in [client/src/helpers/filters/filters.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/src/helpers/filters/filters.json).
<a id="uses"></a>
## Projects that use AdGuardHome
@@ -242,5 +294,3 @@ This software wouldn't have been possible without:
You might have seen that [CoreDNS](https://coredns.io) was mentioned here before — we've stopped using it in AdGuardHome. While we still use it on our servers for [AdGuard DNS](https://adguard.com/adguard-dns/overview.html) service, it seemed like an overkill for Home as it impeded with Home features that we plan to implement.
For a full list of all node.js packages in use, please take a look at [client/package.json](https://github.com/AdguardTeam/AdGuardHome/blob/master/client/package.json) file.
For info on which exact domains that are blocked by the *Blocked services* function, it can be found at [dnsfilter/blocked_services.go](https://github.com/AdguardTeam/AdGuardHome/blob/master/dnsfilter/blocked_services.go)

View File

@@ -1,74 +0,0 @@
#!/usr/bin/env bash
set -eE
set -o pipefail
set -x
DOCKERFILE="packaging/docker/Dockerfile.hub"
IMAGE_NAME="adguard/adguardhome"
if [[ "${TRAVIS_BRANCH}" == "master" ]]
then
VERSION="edge"
else
VERSION=`git describe --abbrev=4 --dirty --always --tags`
fi
build_image() {
from="$(awk '$1 == toupper("FROM") { print $2 }' ${DOCKERFILE})"
# See https://hub.docker.com/r/multiarch/alpine/tags
case "${GOARCH}" in
arm64)
alpineArch='arm64-edge'
imageArch='arm64'
;;
arm)
alpineArch='armhf-edge'
imageArch='armhf'
;;
386)
alpineArch='i386-edge'
imageArch='i386'
;;
amd64)
alpineArch='amd64-edge'
;;
*)
alpineArch='amd64-edge'
;;
esac
if [[ "${GOOS}" == "linux" ]] && [[ "${GOARCH}" == "amd64" ]]
then
image="${IMAGE_NAME}:${VERSION}"
else
image="${IMAGE_NAME}:${imageArch}-${VERSION}"
fi
make cleanfast; CGO_DISABLED=1 make
docker pull "multiarch/alpine:${alpineArch}"
docker tag "multiarch/alpine:${alpineArch}" "$from"
docker build -t "${image}" -f ${DOCKERFILE} .
docker push ${image}
if [[ "${VERSION}" != "edge" ]]
then
latest=${image/$VERSION/latest}
docker tag "${image}" "${latest}"
docker push ${latest}
docker rmi ${latest}
fi
docker rmi "$from"
}
# prepare qemu
docker run --rm --privileged multiarch/qemu-user-static:register --reset
make clean
# Prepare releases
GOOS=linux GOARCH=amd64 build_image
GOOS=linux GOARCH=386 build_image
GOOS=linux GOARCH=arm GOARM=6 build_image
GOOS=linux GOARCH=arm64 GOARM=6 build_image

View File

@@ -1,73 +0,0 @@
#!/usr/bin/env bash
set -eE
set -o pipefail
set -x
channel=${1:-release}
baseUrl="https://static.adguard.com/adguardhome/$channel"
dst=dist
version=`git describe --abbrev=4 --dirty --always --tags`
f() {
make cleanfast; CGO_DISABLED=1 make
if [[ $GOOS == darwin ]]; then
zip $dst/AdGuardHome_MacOS.zip AdGuardHome README.md LICENSE.txt
elif [[ $GOOS == windows ]]; then
zip $dst/AdGuardHome_Windows_"$GOARCH".zip AdGuardHome.exe README.md LICENSE.txt
else
rm -rf dist/AdguardHome
mkdir -p dist/AdGuardHome
cp -pv {AdGuardHome,LICENSE.txt,README.md} dist/AdGuardHome/
pushd dist
if [[ $GOARCH == arm ]] && [[ $GOARM != 6 ]]; then
tar zcvf AdGuardHome_"$GOOS"_armv"$GOARM".tar.gz AdGuardHome/
else
tar zcvf AdGuardHome_"$GOOS"_"$GOARCH".tar.gz AdGuardHome/
fi
popd
rm -rf dist/AdguardHome
fi
}
# Clean dist and build
make clean
rm -rf $dst
# Prepare the dist folder
mkdir -p $dst
# Prepare releases
CHANNEL=$channel GOOS=darwin GOARCH=amd64 f
CHANNEL=$channel GOOS=linux GOARCH=amd64 f
CHANNEL=$channel GOOS=linux GOARCH=386 GO386=387 f
CHANNEL=$channel GOOS=linux GOARCH=arm GOARM=5 f
CHANNEL=$channel GOOS=linux GOARCH=arm GOARM=6 f
CHANNEL=$channel GOOS=linux GOARCH=arm64 GOARM=6 f
CHANNEL=$channel GOOS=windows GOARCH=amd64 f
CHANNEL=$channel GOOS=windows GOARCH=386 f
CHANNEL=$channel GOOS=linux GOARCH=mipsle GOMIPS=softfloat f
CHANNEL=$channel GOOS=linux GOARCH=mips GOMIPS=softfloat f
CHANNEL=$channel GOOS=freebsd GOARCH=amd64 f
# Variables for CI
echo "version=$version" > $dst/version.txt
# Prepare the version.json file
echo "{" >> $dst/version.json
echo " \"version\": \"$version\"," >> $dst/version.json
echo " \"announcement\": \"AdGuard Home $version is now available!\"," >> $dst/version.json
echo " \"announcement_url\": \"https://github.com/AdguardTeam/AdGuardHome/releases\"," >> $dst/version.json
echo " \"download_windows_amd64\": \"$baseUrl/AdGuardHome_Windows_amd64.zip\"," >> $dst/version.json
echo " \"download_windows_386\": \"$baseUrl/AdGuardHome_Windows_386.zip\"," >> $dst/version.json
echo " \"download_darwin_amd64\": \"$baseUrl/AdGuardHome_MacOS.zip\"," >> $dst/version.json
echo " \"download_linux_amd64\": \"$baseUrl/AdGuardHome_linux_amd64.tar.gz\"," >> $dst/version.json
echo " \"download_linux_386\": \"$baseUrl/AdGuardHome_linux_386.tar.gz\"," >> $dst/version.json
echo " \"download_linux_arm\": \"$baseUrl/AdGuardHome_linux_arm.tar.gz\"," >> $dst/version.json
echo " \"download_linux_armv5\": \"$baseUrl/AdGuardHome_linux_armv5.tar.gz\"," >> $dst/version.json
echo " \"download_linux_arm64\": \"$baseUrl/AdGuardHome_linux_arm64.tar.gz\"," >> $dst/version.json
echo " \"download_linux_mips\": \"$baseUrl/AdGuardHome_linux_mips.tar.gz\"," >> $dst/version.json
echo " \"download_linux_mipsle\": \"$baseUrl/AdGuardHome_linux_mipsle.tar.gz\"," >> $dst/version.json
echo " \"download_freebsd_amd64\": \"$baseUrl/AdGuardHome_freebsd_amd64.tar.gz\"," >> $dst/version.json
echo " \"selfupdate_min_version\": \"v0.0\"" >> $dst/version.json
echo "}" >> $dst/version.json

View File

@@ -1,292 +0,0 @@
#!/usr/bin/env bash
set -eE
set -o pipefail
set -x
BUILDER_IMAGE="adguard/snapcraft:1.0"
SNAPCRAFT_TMPL="packaging/snap/snapcraft.yaml"
SNAP_NAME="adguard-home"
LAUNCHPAD_CREDENTIALS_DIR=".local/share/snapcraft/provider/launchpad"
if [[ -z ${VERSION} ]]; then
VERSION=$(git describe --abbrev=4 --dirty --always --tags)
echo "VERSION env variable is not set, getting it from git: ${VERSION}"
fi
# If bash is interactive, set `-it` parameter for docker run
INTERACTIVE=""
if [ -t 0 ]; then
INTERACTIVE="-it"
fi
function usage() {
cat <<EOF
Usage: ${0##*/} command [options]
Please note that in order for the builds to work properly, you need to setup some env variables.
These are necessary for "remote-build' command.
Read this doc on how to generate them: https://uci.readthedocs.io/en/latest/oauth.html
* LAUNCHPAD_KEY -- launchpad CI key
* LAUNCHPAD_ACCESS_TOKEN -- launchpad access token
* LAUNCHPAD_ACCESS_SECRET -- launchpad access secret
These are necessary for snapcraft publish command to work.
They can be exported using "snapcraft export-login"
* SNAPCRAFT_MACAROON
* SNAPCRAFT_UBUNTU_DISCHARGE
* SNAPCRAFT_EMAIL
Examples:
${0##*/} build-docker - builds snaps using remote-build inside a Docker environment
${0##*/} build - builds snaps using remote-build
${0##*/} publish-docker-beta - publishes snaps to the beta channel using Docker environment
${0##*/} publish-docker-release - publishes snaps to the release channel using Docker environment
${0##*/} publish-beta - publishes snaps to the beta channel
${0##*/} publish-release - publishes snaps to the release channel
${0##*/} cleanup - clean up temporary files that were created by the builds
EOF
exit 1
}
#######################################
# helper functions
#######################################
function prepare() {
if [ -z "${LAUNCHPAD_KEY}" ] || [ -z "${LAUNCHPAD_ACCESS_TOKEN}" ] || [ -z "${LAUNCHPAD_ACCESS_SECRET}" ]; then
echo "Launchpad oauth tokens are not set, exiting"
usage
exit 1
fi
if [ -z "${SNAPCRAFT_MACAROON}" ] || [ -z "${SNAPCRAFT_UBUNTU_DISCHARGE}" ] || [ -z "${SNAPCRAFT_EMAIL}" ]; then
echo "Snapcraft auth params are not set, exiting"
usage
exit 1
fi
# Launchpad oauth tokens data is necessary to run snapcraft remote-build
#
# Here's an instruction on how to generate launchpad OAuth tokens:
# https://uci.readthedocs.io/en/latest/oauth.html
#
# Launchpad credentials are necessary to run snapcraft remote-build command
echo "[1]
consumer_key = ${LAUNCHPAD_KEY}
consumer_secret =
access_token = ${LAUNCHPAD_ACCESS_TOKEN}
access_secret = ${LAUNCHPAD_ACCESS_SECRET}
" >launchpad_credentials
# Snapcraft login data
# It can be exported using snapcraft export-login command
echo "[login.ubuntu.com]
macaroon = ${SNAPCRAFT_MACAROON}
unbound_discharge = ${SNAPCRAFT_UBUNTU_DISCHARGE}
email = ${SNAPCRAFT_EMAIL}" >snapcraft_login
# Prepare the snap configuration
cp ${SNAPCRAFT_TMPL} ./snapcraft.yaml
sed -i.bak 's/dev_version/'"${VERSION}"'/g' ./snapcraft.yaml
rm -f snapcraft.yaml.bak
}
build_snap() {
# prepare credentials
prepare
# copy them to the directory where snapcraft will be able to read them
mkdir -p ~/${LAUNCHPAD_CREDENTIALS_DIR}
cp -f snapcraft_login ~/${LAUNCHPAD_CREDENTIALS_DIR}/credentials
chmod 600 ~/${LAUNCHPAD_CREDENTIALS_DIR}/credentials
# run the build
snapcraft remote-build --build-on=${ARCH} --launchpad-accept-public-upload
# remove the credentials - we don't need them anymore
rm -rf ~/${LAUNCHPAD_CREDENTIALS_DIR}
# remove version from the file name
rename_snap_file
# cleanup credentials
cleanup
}
build_snap_docker() {
# prepare credentials
prepare
docker run ${INTERACTIVE} --rm \
-v $(pwd):/build \
-v $(pwd)/launchpad_credentials:/root/${LAUNCHPAD_CREDENTIALS_DIR}/credentials:ro \
${BUILDER_IMAGE} \
snapcraft remote-build --build-on=${ARCH} --launchpad-accept-public-upload
# remove version from the file name
rename_snap_file
# cleanup credentials
cleanup
}
rename_snap_file() {
# In order to make working with snaps easier later on
# we remove version from the file name
# Check that the snap file exists
snapFile="${SNAP_NAME}_${VERSION}_${ARCH}.snap"
if [ ! -f ${snapFile} ]; then
echo "Snap file ${snapFile} not found!"
exit 1
fi
mv -f ${snapFile} "${SNAP_NAME}_${ARCH}.snap"
}
publish_snap() {
# prepare credentials
prepare
# Check that the snap file exists
snapFile="${SNAP_NAME}_${ARCH}.snap"
if [ ! -f ${snapFile} ]; then
echo "Snap file ${snapFile} not found!"
exit 1
fi
# Login if necessary
snapcraft login --with=snapcraft_login
# Push to the channel
snapcraft push --release=${CHANNEL} ${snapFile}
# cleanup credentials
cleanup
}
publish_snap_docker() {
# prepare credentials
prepare
# Check that the snap file exists
snapFile="${SNAP_NAME}_${ARCH}.snap"
if [ ! -f ${snapFile} ]; then
echo "Snap file ${snapFile} not found!"
exit 1
fi
# Login and publish the snap
docker run ${INTERACTIVE} --rm \
-v $(pwd):/build \
${BUILDER_IMAGE} \
sh -c "snapcraft login --with=/build/snapcraft_login && snapcraft push --release=${CHANNEL} /build/${snapFile}"
# cleanup credentials
cleanup
}
#######################################
# main functions
#######################################
build() {
if [[ -n "$1" ]]; then
echo "ARCH is set to $1"
ARCH=$1 build_snap
else
ARCH=i386 build_snap
ARCH=arm64 build_snap
ARCH=armhf build_snap
ARCH=amd64 build_snap
fi
}
build_docker() {
if [[ -n "$1" ]]; then
echo "ARCH is set to $1"
ARCH=$1 build_snap_docker
else
ARCH=i386 build_snap_docker
ARCH=arm64 build_snap_docker
ARCH=armhf build_snap_docker
ARCH=amd64 build_snap_docker
fi
}
publish_docker() {
if [[ -z $1 ]]; then
echo "No channel specified"
exit 1
fi
CHANNEL="${1}"
if [ "$CHANNEL" != "stable" ] && [ "$CHANNEL" != "beta" ]; then
echo "$CHANNEL is an invalid value for the update channel!"
exit 1
fi
if [[ -n "$2" ]]; then
echo "ARCH is set to $2"
ARCH=$2 publish_snap_docker
else
ARCH=i386 publish_snap_docker
ARCH=arm64 publish_snap_docker
ARCH=armhf publish_snap_docker
ARCH=amd64 publish_snap_docker
fi
}
publish() {
if [[ -z $1 ]]; then
echo "No channel specified"
exit 1
fi
CHANNEL="${1}"
if [ "$CHANNEL" != "stable" ] && [ "$CHANNEL" != "beta" ]; then
echo "$CHANNEL is an invalid value for the update channel!"
exit 1
fi
if [[ -n "$2" ]]; then
echo "ARCH is set to $2"
ARCH=$2 publish_snap
else
ARCH=i386 publish_snap
ARCH=arm64 publish_snap
ARCH=armhf publish_snap
ARCH=amd64 publish_snap
fi
}
cleanup() {
rm -f launchpad_credentials
rm -f snapcraft.yaml
rm -f snapcraft.yaml.bak
rm -f snapcraft_login
git checkout snapcraft.yaml
}
#######################################
# main
#######################################
if [[ -z $1 || $1 == "--help" || $1 == "-h" ]]; then
usage
fi
case "$1" in
"build-docker") build_docker $2 ;;
"build") build $2 ;;
"publish-docker-beta") publish_docker beta $2 ;;
"publish-docker-release") publish_docker stable $2 ;;
"publish-beta") publish beta $2 ;;
"publish-release") publish stable $2 ;;
"prepare") prepare ;;
"cleanup") cleanup ;;
*) usage ;;
esac
exit 0

36
ci.sh
View File

@@ -1,36 +0,0 @@
#!/bin/bash
set -e
set -x
echo "Starting AdGuard Home CI script"
# Print the current directory contents
ls -la
# Check versions and current directory
node -v
npm -v
go version
golangci-lint --version
# Run linter
golangci-lint run
# Make
make clean
make build/static/index.html
make
# Run tests
go test -race -v -bench=. -coverprofile=coverage.txt -covermode=atomic ./...
# if [[ -z "$(git status --porcelain)" ]]; then
# # Working directory clean
# echo "Git status is clean"
# else
# echo "Git status is not clean and contains uncommited changes"
# echo "Please make sure there are no changes"
# exit 1
# fi
echo "AdGuard Home CI script finished successfully"

View File

@@ -9,6 +9,8 @@ module.exports = (api) => {
'@babel/plugin-proposal-class-properties',
'@babel/plugin-transform-runtime',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-optional-chaining',
],
};
};

114
client/package-lock.json generated vendored
View File

@@ -472,13 +472,21 @@
}
},
"@babel/plugin-proposal-nullish-coalescing-operator": {
"version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz",
"integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==",
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz",
"integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
"integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
"dev": true
}
}
},
"@babel/plugin-proposal-numeric-separator": {
@@ -513,13 +521,21 @@
}
},
"@babel/plugin-proposal-optional-chaining": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz",
"integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==",
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz",
"integrity": "sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.8.3",
"@babel/helper-plugin-utils": "^7.10.4",
"@babel/plugin-syntax-optional-chaining": "^7.8.0"
},
"dependencies": {
"@babel/helper-plugin-utils": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
"integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
"dev": true
}
}
},
"@babel/plugin-proposal-unicode-property-regex": {
@@ -4498,6 +4514,15 @@
"sha.js": "^2.4.8"
}
},
"create-react-context": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz",
"integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==",
"requires": {
"gud": "^1.0.0",
"warning": "^4.0.3"
}
},
"cross-env": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz",
@@ -4800,7 +4825,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"dev": true,
"requires": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
@@ -4836,7 +4860,6 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"dev": true,
"requires": {
"object-keys": "^1.0.12"
}
@@ -5264,7 +5287,6 @@
"version": "1.17.5",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
"integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
@@ -5283,7 +5305,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
@@ -6706,8 +6727,7 @@
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"functional-red-black-tree": {
"version": "1.0.1",
@@ -6989,6 +7009,11 @@
"dev": true,
"optional": true
},
"gud": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
},
"handle-thing": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@@ -7021,7 +7046,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
@@ -7034,8 +7058,7 @@
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
"dev": true
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
},
"has-value": {
"version": "1.0.0",
@@ -7759,8 +7782,7 @@
"is-arguments": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
"integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
"dev": true
"integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
},
"is-arrayish": {
"version": "0.2.1",
@@ -7785,8 +7807,7 @@
"is-callable": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q=="
},
"is-ci": {
"version": "2.0.0",
@@ -7820,8 +7841,7 @@
"is-date-object": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
"dev": true
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g=="
},
"is-decimal": {
"version": "1.0.4",
@@ -7974,7 +7994,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
@@ -8000,7 +8019,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
"integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
"dev": true,
"requires": {
"has-symbols": "^1.0.1"
}
@@ -11117,14 +11135,12 @@
"object-inspect": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
"integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
"dev": true
"integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
},
"object-is": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
"integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
@@ -11133,8 +11149,7 @@
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object-visit": {
"version": "1.0.1",
@@ -11149,7 +11164,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"function-bind": "^1.1.1",
@@ -11630,6 +11644,11 @@
"find-up": "^2.1.0"
}
},
"popper.js": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"portfinder": {
"version": "1.0.26",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz",
@@ -12300,6 +12319,29 @@
"raf": "^3.1.0"
}
},
"react-popper": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz",
"integrity": "sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww==",
"requires": {
"@babel/runtime": "^7.1.2",
"create-react-context": "^0.3.0",
"deep-equal": "^1.1.1",
"popper.js": "^1.14.4",
"prop-types": "^15.6.1",
"typed-styles": "^0.0.7",
"warning": "^4.0.2"
}
},
"react-popper-tooltip": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/react-popper-tooltip/-/react-popper-tooltip-2.11.1.tgz",
"integrity": "sha512-04A2f24GhyyMicKvg/koIOQ5BzlrRbKiAgP6L+Pdj1MVX3yJ1NeZ8+EidndQsbejFT55oW1b++wg2Z8KlAyhfQ==",
"requires": {
"@babel/runtime": "^7.9.2",
"react-popper": "^1.3.7"
}
},
"react-redux": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz",
@@ -12616,7 +12658,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
"integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1"
@@ -13876,7 +13917,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
"integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
@@ -13886,7 +13926,6 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
"integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5",
@@ -13897,7 +13936,6 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
"integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5",
@@ -13908,7 +13946,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
"integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
@@ -14908,6 +14945,11 @@
"mime-types": "~2.1.24"
}
},
"typed-styles": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
"integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",

4
client/package.json vendored
View File

@@ -7,6 +7,7 @@
"watch": "cross-env BUILD_ENV=dev webpack --config webpack.dev.js --watch",
"build-prod": "cross-env BUILD_ENV=prod webpack --config webpack.prod.js",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"test": "jest",
"test:watch": "jest --watch"
},
@@ -26,6 +27,7 @@
"react-dom": "^16.13.1",
"react-i18next": "^11.4.0",
"react-modal": "^3.11.2",
"react-popper-tooltip": "^2.11.1",
"react-redux": "^7.2.0",
"react-redux-loading-bar": "^4.6.0",
"react-router-dom": "^5.2.0",
@@ -42,7 +44,9 @@
"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
"@babel/plugin-proposal-object-rest-spread": "^7.9.6",
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
"@babel/plugin-transform-runtime": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"@babel/preset-react": "^7.9.4",

View File

@@ -1,16 +1,8 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="144.000000pt" height="144.000000pt" viewBox="0 0 144.000000 144.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,144.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M485 1424 c-159 -24 -332 -74 -449 -130 l-39 -19 6 -130 c4 -71 13
-166 21 -210 66 -364 268 -656 608 -883 89 -59 79 -59 176 4 336 218 540 516
608 884 11 60 14 91 20 216 l6 120 -78 33 c-267 112 -604 156 -879 115z"/>
</g>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16pt" height="16pt"
viewBox="0 0 16 16" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;"
d="M 8 0 C 10.5 0 13.515625 0.574219 16 1.835938 L 15.996094 2.542969 C 15.957031 5.605469 15.410156 11.71875 8 16 C 0.5 11.667969 0.03125 5.460938 0.00390625 2.433594 L 0 1.835938 C 2.484375 0.574219 5.5 0 8 0 Z M 11.769531 4.203125 L 11.761719 4.203125 L 7.890625 8.160156 L 6.433594 6.4375 C 5.738281 5.644531 4.792969 6.25 4.570312 6.40625 L 7.929688 10.285156 L 12.570312 4.136719 C 12.230469 3.867188 11.933594 4.054688 11.769531 4.203125 Z M 11.769531 4.203125 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 743 B

After

Width:  |  Height:  |  Size: 801 B

View File

@@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<meta name="google" content="notranslate">
<meta http-equiv="x-dns-prefetch-control" content="off">
<link rel="apple-touch-icon" sizes="180x180" href="assets/apple-touch-icon-180x180.png" />
<link rel="mask-icon" href="assets/safari-pinned-tab.svg" color="#5bbad5">
<link rel="mask-icon" href="assets/safari-pinned-tab.svg" color="#67B279">
<link rel="icon" type="image/png" href="assets/favicon.png" sizes="48x48">
<title>AdGuard Home</title>
</head>

View File

@@ -2,11 +2,11 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<meta name="google" content="notranslate">
<link rel="apple-touch-icon" sizes="180x180" href="assets/apple-touch-icon-180x180.png" />
<link rel="mask-icon" href="assets/safari-pinned-tab.svg" color="#5bbad5">
<link rel="mask-icon" href="assets/safari-pinned-tab.svg" color="#67B279">
<link rel="icon" type="image/png" href="assets/favicon.png" sizes="48x48">
<title>Setup AdGuard Home</title>
</head>

View File

@@ -2,11 +2,11 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<meta name="google" content="notranslate">
<link rel="apple-touch-icon" sizes="180x180" href="assets/apple-touch-icon-180x180.png" />
<link rel="mask-icon" href="assets/safari-pinned-tab.svg" color="#5bbad5">
<link rel="mask-icon" href="assets/safari-pinned-tab.svg" color="#67B279">
<link rel="icon" type="image/png" href="assets/favicon.png" sizes="48x48">
<title>Login</title>
</head>

View File

@@ -28,6 +28,9 @@
"dhcp_table_hostname": "Име на устройство",
"dhcp_table_expires": "История",
"dhcp_warning": "Ако искате да използвате вградения DHCP сървър, трябва да няма друг активен DHCP в мрежата Ви!",
"city": "Град",
"response_details": "Подробности за отговора",
"request_details": "Поискайте подробности",
"back": "Назад",
"dashboard": "Табло",
"settings": "Настройки",
@@ -35,7 +38,8 @@
"query_log": "История на заявките",
"faq": "ЧЗВ",
"version": "версия",
"address": "адрес",
"address": "Адрес",
"protocol": "Протокол",
"on": "ВКЛЮЧЕНО",
"off": "ИЗКЛЮЧЕНО",
"copyright": "Авторско право",
@@ -97,6 +101,7 @@
"filters_and_hosts_hint": "AdGuard Home разбира adblock и host синтаксис.",
"cancel_btn": "Откажи",
"enter_name_hint": "Въведи име",
"check_updates_btn": "Провери за актуализация",
"custom_filter_rules": "Местни правила за филтриране",
"custom_filter_rules_hint": "Въвеждайте всяко правило на нов ред. Може да използвате adblock или hosts файлов синтаксис.",
"examples_title": "Примери",
@@ -106,6 +111,7 @@
"example_comment": "! Това е коментар",
"example_comment_meaning": "пример за коментар",
"example_comment_hash": "# Това е също коментар",
"example_regex_meaning": "блокирай достъп до домейни който съвпадат със следното",
"example_upstream_regular": "класически DNS (UDP протокол)",
"example_upstream_dot": "криптиран <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-върху-TLS</a>",
"example_upstream_doh": "криптиран <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-върху-HTTPS</a>",
@@ -114,9 +120,10 @@
"updated_upstream_dns_toast": "Глобалните DNS сървъри са обновени",
"dns_test_ok_toast": "Въведените DNS сървъри работят коректно",
"dns_test_not_ok_toast": "Сървър \"{{key}}\": не работи, моля проверете дали е въведен коректно",
"unblock_btn": "Отблокирай",
"block_btn": "Блокирай",
"unblock": "Отблокирай",
"block": "Блокирай",
"time_table_header": "Време",
"date": "Дата",
"domain_name_table_header": "Име на домейн",
"type_table_header": "Тип",
"response_table_header": "Отговор",
@@ -134,6 +141,7 @@
"updated_custom_filtering_toast": "Обновени местни правила за филтриране",
"rule_removed_from_custom_filtering_toast": "Премахнато от местни правила за филтриране",
"rule_added_to_custom_filtering_toast": "Добавено до местни правила за филтриране",
"plain_dns": "Обикновен DNS",
"source_label": "Източник",
"found_in_known_domain_db": "Намерен в списъците с домейни.",
"category_label": "Категория",
@@ -226,5 +234,7 @@
"form_error_equal": "Не трябва да съвпада",
"form_error_password": "Паролата не съвпада",
"reset_settings": "Изтрий всички настройки",
"update_announcement": "Има нова AdGuard Home {{version}}! <0>Цъкни тук</0> за повече информация."
"update_announcement": "Има нова AdGuard Home {{version}}! <0>Цъкни тук</0> за повече информация.",
"disable_ipv6": "Изключете IPv6 протокола",
"show_blocked_responses": "Блокирано"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Můžete zadat DNS upstream <0>pro konkrétní doménu(y)</0>",
"upstream_parallel": "Použijte paralelní požadavky na urychlení řešení simultánním dotazováním na všechny navazující servery",
"parallel_requests": "Paralelní požadavky",
"load_balancing": "Optimalizace vytížení",
"load_balancing_desc": "Optimalizovaný dotaz na server. AdGuard Home použije vážený náhodný algoritmus k výběru serveru, takže nejrychlejší server bude používán častěji.",
"bootstrap_dns": "Bootstrap DNS servery",
"bootstrap_dns_desc": "Servery Bootstrap DNS se používají k řešení IP adres DoH/DoT, které zadáváte jako upstreamy.",
"check_dhcp_servers": "Zkontrolovat DHCP servery",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Vybrat rozhraní DHCP",
"dhcp_hardware_address": "Hardwarová adresa",
"dhcp_ip_addresses": "IP adresa",
"ip": "IP adresa",
"dhcp_table_hostname": "Název hostitele",
"dhcp_table_expires": "Vyprší",
"dhcp_warning": "Pokud chcete server DHCP povolit, ujistěte se, že ve Vaší síti není žádný aktivní server DHCP. V opačném případě může dojít k přerušení internetu pro připojená zařízení!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "Nebyly nalezeny žádné statické pronájmy DHCP",
"dhcp_add_static_lease": "Přidat statický pronájem",
"dhcp_reset": "Opravdu chcete resetovat konfiguraci DHCP?",
"country": "Země",
"city": "Město",
"delete_confirm": "Opravdu chcete odstranit \"{{key}}\"?",
"form_enter_hostname": "Zadejte název hostitele",
"error_details": "Podrobnosti chyby",
"response_details": "Detail odpovědi",
"request_details": "Detail požadavku",
"client_details": "Detaily klienta",
"details": "Detaily",
"back": "Zpět",
"dashboard": "Hlavní panel",
"settings": "Nastavení",
"filters": "Filtry",
"filter": "Filtr",
"query_log": "Protokol dotazů",
"compact": "Kompaktní",
"nothing_found": "Nic nenalezeno",
"faq": "FAQ",
"version": "Verze",
"address": "adresa",
"address": "Adresa",
"protocol": "Protokol",
"on": "ZAPNUTO",
"off": "VYPNUTO",
"copyright": "Autorská práva",
@@ -113,7 +126,7 @@
"custom_filtering_rules": "Vlastní pravidla filtrování",
"encryption_settings": "Nastavení šifrování",
"dhcp_settings": "Nastavení DHCP",
"upstream_dns": "Upstream DNS servery",
"upstream_dns": "Odchozí DNS servery",
"upstream_dns_hint": "Pokud toto pole ponecháte prázdné, AdGuard Home použije <a href='https://www.quad9.net/' target='_blank'>Quad9</a> jako upstream.",
"test_upstream_btn": "Test upstreamů",
"upstreams": "Odesláno",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Počet pravidel",
"last_time_updated_table_header": "Čas poslední aktualizace",
"actions_table_header": "Akce",
"request_table_header": "Požadavek",
"edit_table_action": "Upravit",
"delete_table_action": "Vymazat",
"elapsed": "Uplynulý čas",
"filters_and_hosts_hint": "AdGuard Home zná základní pravidla blokování reklam a syntaxe hostsitelských souborů.",
"no_blocklist_added": "Nebyl přidán žádný seznam blokovaných",
"no_whitelist_added": "Nebyl přidán žádný seznam povolených",
@@ -170,12 +185,15 @@
"updated_upstream_dns_toast": "Aktualizované upstream DNS servery",
"dns_test_ok_toast": "Specifikované DNS servery pracují správně",
"dns_test_not_ok_toast": "Server \"{{key}}\": nemohl být použit, zkontrolujte, zda jste ho správně napsali",
"unblock_btn": "Odblokovat",
"block_btn": "Blokovat",
"unblock": "Odblokovat",
"block": "Blokovat",
"time_table_header": "Čas",
"date": "Datum",
"domain_name_table_header": "Název domény",
"domain_or_client": "Doména nebo klient",
"type_table_header": "Typ",
"response_table_header": "Odezva",
"response_code": "Kód odezvy",
"client_table_header": "Klient",
"empty_response_status": "Prázdná",
"show_all_filter_type": "Zobrazit vše",
@@ -194,6 +212,7 @@
"query_log_filtered": "Filtrováno pomocí {{filter}}",
"query_log_confirm_clear": "Opravdu chcete vymazat celý protokol dotazů?",
"query_log_cleared": "Protokol dotazů byl úspěšně vymazán",
"query_log_updated": "Protokol dotazů byl úspěšně aktualizován",
"query_log_clear": "Vymazat protokoly dotazů",
"query_log_retention": "Uchování protokolů dotazů",
"query_log_enable": "Povolit protokol",
@@ -211,6 +230,9 @@
"custom_ip": "Vlastní IP",
"blocking_ipv4": "Blokování IPv4",
"blocking_ipv6": "Blokování IPv6",
"dns_over_https": "DNS přes HTTPS",
"dns_over_tls": "DNS přes TLS",
"plain_dns": "Čisté DNS",
"form_enter_rate_limit": "Zadejte rychlostní limit",
"rate_limit": "Rychlostní limit",
"edns_enable": "Povolit klientskou podsíť EDNS",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Nulová IP: Odezva s nulovou IP adresou (0.0.0.0 pro A; :: pro AAAA)",
"blocking_mode_custom_ip": "Vlastní IP. odezva s ručně nastavenou IP adresou",
"upstream_dns_client_desc": "Pokud toto pole ponecháte prázdné, AdGuard Home použije servery nakonfigurované v<0>DNS nastavení</0>.",
"tracker_source": "Zdroj slídiče",
"source_label": "Zdroj",
"found_in_known_domain_db": "Nalezeno v databázi známých domén",
"category_label": "Kategorie",
"rule_label": "Pravidlo",
"list_label": "Seznam",
"unknown_filter": "Neznámý filtr {{filterId}}",
"known_tracker": "Známý slídič",
"install_welcome_title": "Vítejte v AdGuard Home!",
"install_welcome_desc": "AdGuard Home je síťový DNS server pro blokování reklam a slídičů. Jeho cílem je, abyste ovládali celou Vaši síť a všechny Vaše zařízení, přičemž se nevyžaduje použití jakéhokoliv programu na straně klienta.",
"install_settings_title": "Administrátorské webové rozhraní",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "Otevřete předvolby pro router. Obvykle k němu můžete přistupovat z prohlížeče prostřednictvím adresy URL (např. http://192.168.0.1/ nebo http://192.168.1.1/). Můžete být vyzváni k zadání hesla. Pokud si ho nepamatujete, můžete heslo resetovat stisknutím tlačítka na samotném routeru. Některé routery vyžadují specifickou aplikaci, která by v takovém případě měla být již nainstalována v počítači/telefonu.",
"install_devices_router_list_2": "Vyhledejte nastavení DHCP/DNS. Hledejte zkratku DNS vedle pole, které umožňuje vložit dvě nebo tři sady čísel, každé rozděleno do čtyř skupin s jedním až třemi číslicemi.",
"install_devices_router_list_3": "Zadejte adresy Vašeho serveru AdGuard Home.",
"install_devices_router_list_4": "Na některých typech routerů nemůžete nastavit vlastní DNS server. V tomto případě může AdGuard Home pomoct pokud jej nastavíte jako DHCP server. V ostatních případech byste si v manuálu k Vašemu routeru měli zjistit, jak nastavit vlastní DNS servery.",
"install_devices_router_list_4": "Na některých typech routerů nemůžete nastavit vlastní DNS server. V tomto případě může AdGuard Home pomoci, pokud jej nastavíte jako <0>DHCP server</0>. V ostatních případech byste si v manuálu k Vašemu routeru měli zjistit, jak nastavit vlastní DNS servery.",
"install_devices_windows_list_1": "Otevřete ovládací panel prostřednictvím nabídky Start nebo vyhledání v systému Windows.",
"install_devices_windows_list_2": "Přejděte na kategorii Síť a Internet a poté na Centrum sítí a sdílení.",
"install_devices_windows_list_3": "Na levé straně obrazovky najděte možnost Změnit nastavení adaptéru a klepněte na něj.",
@@ -346,6 +370,7 @@
"form_enter_id": "Zadejte identifikátor",
"form_add_id": "Přidat identifikátor",
"form_client_name": "Zadejte název klienta",
"name": "Název",
"client_global_settings": "Použít globální nastavení",
"client_deleted": "Klient \"{{key}}\" byl úspěšně odstraněn",
"client_added": "Klient \"{{key}}\" byl úspěšně přidán",
@@ -445,6 +470,7 @@
"location": "Umístění",
"orgname": "Název organizace",
"netname": "Název sítě",
"network": "Síť",
"descr": "Popis",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Další informace</0> o vytváření vlastních seznamů hostitelů.",
@@ -456,7 +482,7 @@
"disable_ipv6": "Zakázat IPv6",
"disable_ipv6_desc": "Pokud je tato funkce povolena, budou všechny dotazy DNS pro adresy IPv6 (typ AAAA) zrušeny.",
"fastest_addr": "Nejrychlejší IP adresa",
"fastest_addr_desc": "Dotazovat všechny DNS servery a vrátit nejrychlejší IP adresu ze všech odpovědí",
"fastest_addr_desc": "Dotazovat všechny DNS servery a vrátit nejrychlejší IP adresu ze všech odpovědí. To zpomalí dotazy DNS, protože musíme čekat na odpovědi ze všech serverů DNS, ale celková konektivita se zlepší.",
"autofix_warning_text": "Pokud kliknete na „Opravit“, AdGuard Home nakonfiguruje váš systém tak, aby používal DNS server AdGuard Home.",
"autofix_warning_list": "Jsou prováděny následující úlohy: <0>Deaktivace systému DNSStubListener</0> <0>Nastavení adresy serveru DNS na 127.0.0.1</0> <0>Nahrazení cíle symbolického odkazu z /etc/resolv.conf do /run/systemd/resolve/resolv.conf</0> <0>Zastavení služby DNSStubListener (znovu načtení služby systemd-resolved)</0>",
"autofix_warning_result": "Výsledkem je, že všechny požadavky DNS z vašeho systému jsou ve výchozím nastavení zpracovány službou AdGuard Home.",
@@ -489,5 +515,19 @@
"list_updated": "Byl aktualizován {{count}} seznam",
"list_updated_plural": "Aktualizované seznamy: {{count}}",
"dnssec_enable": "Zapnout DNSSEC",
"dnssec_enable_desc": "Nastavte příznak DNSSEC v následujících DNS dotazech a zkontrolujte výsledek (je potřebný překladač se zapnutým DNSSEC)"
"dnssec_enable_desc": "Nastavte příznak DNSSEC v následujících DNS dotazech a zkontrolujte výsledek (je potřebný překladač se zapnutým DNSSEC)",
"validated_with_dnssec": "Ověřeno pomocí DNSSEC",
"show_all_responses": "Všechny odpovědi",
"show_blocked_responses": "Zablokované",
"show_whitelisted_responses": "Povolené",
"show_processed_responses": "Zpracovaný",
"blocked_safebrowsing": "Blokované bezpečné prohlížení",
"blocked_adult_websites": "Blokované stránky pro dospělé",
"blocked_threats": "Blokované hrozby",
"allowed": "Povoleno",
"filtered": "Filtrováno",
"rewritten": "Přepsáno",
"safe_search": "Bezpečné vyhledávání",
"blocklist": "Zakázaný",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Du kan specificere DNS upstream <0>for det(de) specifikke domæne(r)</0>",
"upstream_parallel": "Brug parallelle forespørgsler til at fremskynde behandlingen ved samtidig at spørge alle upstream servere",
"parallel_requests": "Parallelle forespørgsler",
"load_balancing": "Belastningsfordeling",
"load_balancing_desc": "Forespørg en server ad gangen. AdGuard Home bruger den vægtede tilfældige algoritme til at vælge serveren, så den hurtigste server bliver brugt oftere.",
"bootstrap_dns": "Bootstrap DNS-servere",
"bootstrap_dns_desc": "Bootstrap DNS-servere bliver brugt til at behandle IP-adresser af de DoH/DoT resolvere, som du angiver som upstream.",
"check_dhcp_servers": "Tjek for DHCP-servere",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Vælg DHCP-interface",
"dhcp_hardware_address": "Hardware-adresse",
"dhcp_ip_addresses": "IP-adresser",
"ip": "IP",
"dhcp_table_hostname": "Værtsnavn",
"dhcp_table_expires": "Udløber",
"dhcp_warning": "Hvis du vil aktivere DHCP-serveren alligevel, skal du sørge for, at der ikke er nogen anden aktiv DHCP-server på dit netværk. Ellers kan det ødelægge internettet for tilsluttede enheder!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "Ingen DHCP static leases fundet",
"dhcp_add_static_lease": "Tilføj static lease",
"dhcp_reset": "Er du sikker på, at du vil nulstille DHCP-konfigurationen?",
"country": "Land",
"city": "By",
"delete_confirm": "Er du sikker på, at du vil slette \"{{key}}\"?",
"form_enter_hostname": "Indtast værtsnavn",
"error_details": "Fejloplysninger",
"response_details": "Svardetaljer",
"request_details": "Anmod om detaljer",
"client_details": "Klientoplysninger",
"details": "Detaljer",
"back": "Tilbage",
"dashboard": "Kontrolpanel",
"settings": "Indstillinger",
"filters": "Filtre",
"filter": "Filter",
"query_log": "Forespørgselslog",
"compact": "Kompakt",
"nothing_found": "Intet blev fundet",
"faq": "FAQ",
"version": "Version",
"address": "adresse",
"address": "Adresse",
"protocol": "Protokol",
"on": "TÆNDT",
"off": "SLUKKET",
"copyright": "Copyright",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Antal regler",
"last_time_updated_table_header": "Sidst opdateret",
"actions_table_header": "Handlinger",
"request_table_header": "Forespørgsel",
"edit_table_action": "Rediger",
"delete_table_action": "Slet",
"elapsed": "Varighed",
"filters_and_hosts_hint": "AdGuard Home forstår de grundlæggende annonceblokeringsregler og værtsfilsyntaks.",
"no_blocklist_added": "Ingen blokeringslister tilføjet",
"no_whitelist_added": "Ingen lister over tilladte tilføjet",
@@ -170,12 +185,15 @@
"updated_upstream_dns_toast": "Opdaterede upstream DNS-servere",
"dns_test_ok_toast": "De angivne DNS-servere fungerer korrekt",
"dns_test_not_ok_toast": "Server \"{{key}}\": kunne ikke bruges, kontroller venligst at du har skrevet det korrekt",
"unblock_btn": "Fjern blokering",
"block_btn": "Bloker",
"unblock": "Fjern blokering",
"block": "Bloker",
"time_table_header": "Tid",
"date": "Dato",
"domain_name_table_header": "Domænenavn",
"domain_or_client": "Domæne eller klient",
"type_table_header": "Type",
"response_table_header": "Svar",
"response_code": "Responskode",
"client_table_header": "Klient",
"empty_response_status": "Tom",
"show_all_filter_type": "Vis alle",
@@ -194,6 +212,7 @@
"query_log_filtered": "Filtreret af {{filter}}",
"query_log_confirm_clear": "Er du sikker på, at du vil rydde hele forespørgselsloggen?",
"query_log_cleared": "Forespørgselsloggen er blevet ryddet",
"query_log_updated": "Forespørgselsloggen er blevet opdateret",
"query_log_clear": "Ryd forespørgselslogfiler",
"query_log_retention": "Opbevaring af forespørgselslogfiler",
"query_log_enable": "Aktivér log",
@@ -211,6 +230,9 @@
"custom_ip": "Tilpasset IP",
"blocking_ipv4": "IPv4-blokering",
"blocking_ipv6": "IPv6-blokering",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "Almindelig DNS",
"form_enter_rate_limit": "Indtast hyppighedsgrænse",
"rate_limit": "Hyppighedsgrænse",
"edns_enable": "Aktiver EDNS Client Subnet",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Null IP: Svar med nul IP-adresse (0.0.0.0 for A; :: for AAAA)",
"blocking_mode_custom_ip": "Brugerdefineret IP: Svar med en manuelt indstillet IP-adresse",
"upstream_dns_client_desc": "Hvis du lader dette felt være tomt, vil AdGuard Home bruge de servere, der er konfigureret i <0>DNS-indstillingerne</0>.",
"tracker_source": "Tracker-kilde",
"source_label": "Kilde",
"found_in_known_domain_db": "Fundet i databasen med kendte domæner.",
"category_label": "Kategori",
"rule_label": "Regel",
"list_label": "Liste",
"unknown_filter": "Ukendt filter {{filterId}}",
"known_tracker": "Kendt tracker",
"install_welcome_title": "Velkommen til AdGuard Home!",
"install_welcome_desc": "AdGuard Home er en netværksbaseret annonce-og-tracker blokerende DNS-server. Formålet er at lade dig kontrollere hele dit netværk og alle dine enheder, og det kræver ikke at man bruger klientsoftware.",
"install_settings_title": "Administrator Webgrænseflade",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "Åbn præferencerne for din router. Normalt kan du få adgang til den fra din browser via en URL (som http://192.168.0.1/ eller http://192.168.1.1/). Du bliver muligvis bedt om at indtaste adgangskoden. Hvis du ikke kan huske den, kan du ofte nulstille adgangskoden ved at trykke på en knap på selve routeren. Nogle routere kræver et bestemt program, som i det tilfælde allerede skulle være installeret på din computer/telefon.",
"install_devices_router_list_2": "Find DHCP/DNS-indstillingerne. Kig efter DNS-bogstaverne ved siden af et felt, der tillader to eller tre sæt tal, hver opdelt i fire grupper med et til tre cifre.",
"install_devices_router_list_3": "Indtast dine AdGuard Home serveradresser der.",
"install_devices_router_list_4": "Du kan ikke opsætte en tilpasset DNS-server på nogle typer routere. I dette tilfælde kan det hjælpe, hvis du konfigurerer AdGuard Home som en DHCP-server. Du kan ellers søge efter manualen om, hvordan du tilpasser DNS-servere til din bestemte routermodel.",
"install_devices_router_list_4": "Du kan ikke opsætte en tilpasset DNS-server på nogle typer routere. I dette tilfælde kan det hjælpe, hvis du konfigurerer AdGuard Home som en <0>DHCP-server</0>. Du kan ellers søge efter manualen om, hvordan du tilpasser DNS-servere til din bestemte routermodel.",
"install_devices_windows_list_1": "Åbn Kontrolpanel gennem menuen Start eller Windows søgning.",
"install_devices_windows_list_2": "Gå til Netværk og internet kategorien og derefter til Netværks- og delingscenter.",
"install_devices_windows_list_3": "På venstre side af skærmen finder du Skift adapterindstillinger og klik på den.",
@@ -346,6 +370,7 @@
"form_enter_id": "Indtast identifikator",
"form_add_id": "Tilføj identifikator",
"form_client_name": "Indtast klientnavn",
"name": "Navn",
"client_global_settings": "Brug globale indstillinger",
"client_deleted": "Klient \"{{key}}\" succesfuldt slettet",
"client_added": "Klient \"{{key}}\" succesfuldt tilføjet",
@@ -445,6 +470,7 @@
"location": "Placering",
"orgname": "Organisationens navn",
"netname": "Netværksnavn",
"network": "Netværk",
"descr": "Beskrivelse",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Lær mere</0> om at oprette dine egne værtslister.",
@@ -456,7 +482,7 @@
"disable_ipv6": "Deaktiver IPv6",
"disable_ipv6_desc": "Hvis denne funktion er aktiveret, slettes alle DNS-forespørgsler til IPv6-adresser (type AAAA).",
"fastest_addr": "Hurtigste IP-adresse",
"fastest_addr_desc": "Forespørg alle DNS-servere, og returner den hurtigste IP-adresse blandt alle svar",
"fastest_addr_desc": "Forespørg alle DNS-servere, og returner den hurtigste IP-adresse blandt alle svar. Dette vil gøre DNS-forespørgslerne langsommere, da vi er nødt til at vente på svar fra alle DNS-servere, men forbedrer samlet set forbindelsen.",
"autofix_warning_text": "Hvis du klikker på \"Reparer\", vil AdGuardHome konfigurere dit system til at bruge AdGuardHome DNS-server.",
"autofix_warning_list": "Den vil udføre disse opgaver: <0>Deaktivering af DNSStubListener systemet</0> <0>Indstille DNS-serveradressen til 127.0.0.1</0> <0>Erstatte det symbolske linkmål for /etc/resolv.conf til /run/systemd/resolve/resolv.conf</0> <0>Stop DNSStubListener (genindlæs systemd-løst tjeneste)</0>",
"autofix_warning_result": "Som et resultat behandles alle DNS-anmodninger fra dit system som standard af AdGuard Home.",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} liste opdateret",
"list_updated_plural": "{{count}} lister opdateret",
"dnssec_enable": "Aktivér DNSSEC",
"dnssec_enable_desc": "Sæt DNSSEC-flag i de udgående DNS-forespørgsler, og kontroller resultatet (DNSSEC-aktiveret resolver er krævet)"
"dnssec_enable_desc": "Sæt DNSSEC-flag i de udgående DNS-forespørgsler, og kontroller resultatet (DNSSEC-aktiveret resolver er krævet)",
"validated_with_dnssec": "Valideret med DNSSEC",
"show_all_responses": "Alle svar",
"show_blocked_responses": "Blokeret",
"show_whitelisted_responses": "Hvidlistet",
"show_processed_responses": "Behandlet",
"blocked_safebrowsing": "Blokeret af Safebrowsing",
"blocked_adult_websites": "Blokerede Websteder for Voksne",
"blocked_threats": "Blokerede Trusler",
"allowed": "Tilladt",
"filtered": "Filtreret",
"rewritten": "Omskrevet",
"safe_search": "Sikker søgning",
"blocklist": "Blokeringsliste",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Sie können DNS-Upstream <0>für bestimmte Domain(s)</0> angeben",
"upstream_parallel": "Parallele Abfragen verwenden, um die Lösung zu beschleunigen, indem Sie alle Upstream-Server gleichzeitig abfragen",
"parallel_requests": "Parallele Abfragen",
"load_balancing": "Lastverteilung",
"load_balancing_desc": "Einen Server nach dem anderen abfragen. AdGuard Home verwendet den gewichteten Zufallsalgorithmus, um den Server so auszuwählen, dass der schnellste Server häufiger verwendet wird.",
"bootstrap_dns": "Bootstrap DNS-Server starten",
"bootstrap_dns_desc": "Bootstrap-DNS-Server werden verwendet, um IP-Adressen der DoH/DoT-Resolver aufzulösen, die Sie als Upstreams angeben.",
"check_dhcp_servers": "Auf DHCP-Server prüfen",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "DHCP-Benutzeroberfläche auswählen",
"dhcp_hardware_address": "Hardware-Adresse",
"dhcp_ip_addresses": "IP-Adressen",
"ip": "IP",
"dhcp_table_hostname": "Hostname",
"dhcp_table_expires": "Läuft ab",
"dhcp_warning": "Wenn Sie den DHCP-Server trotzdem aktivieren möchten, stellen Sie sicher, dass sich in Ihrem Netzwerk kein anderer aktiver DHCP-Server befindet. Andernfalls kann es bei angeschlossenen Geräten zu einem Ausfall des Internets kommen!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "Keine statischen DHCP-Leases gefunden",
"dhcp_add_static_lease": "Statischen Lease hinzufügen",
"dhcp_reset": "Möchten Sie die DHCP-Konfiguration wirklich zurücksetzen?",
"country": "Land",
"city": "Stadt",
"delete_confirm": "Möchten Sie „{{key}}” wirklich löschen?",
"form_enter_hostname": "Gerätenamen eingeben",
"error_details": "Fehlerdetails",
"response_details": "Einzelheiten der Antwort",
"request_details": "Einzelheiten der Anfrage",
"client_details": "Einzelheiten des Clients",
"details": "Details",
"back": "Zurück",
"dashboard": "Übersicht",
"settings": "Einstellungen",
"filters": "Filter",
"filter": "Filter",
"query_log": "Anfragenprotokoll",
"compact": "Kompakt",
"nothing_found": "Nichts gefunden\n",
"faq": "FAQ",
"version": "Version",
"address": "Adresse",
"protocol": "Protokoll",
"on": "AN",
"off": "AUS",
"copyright": "Urheberrecht",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Anzahl Regeln",
"last_time_updated_table_header": "Letztes Update",
"actions_table_header": "Aktionen",
"request_table_header": "Anfrage",
"edit_table_action": "Bearbeiten",
"delete_table_action": "Löschen",
"elapsed": "Verstrichen",
"filters_and_hosts_hint": "AdGuard Home versteht grundlegende Werbefilterregeln und Host-Datei-Syntax.",
"no_blocklist_added": "Keine Sperrliste hinzugefügt",
"no_whitelist_added": "Keine Freigabeliste hinzugefügt",
@@ -162,20 +177,23 @@
"example_comment_hash": "# Auch ein Kommentar",
"example_regex_meaning": "Zugriff auf die Domains blockieren, die dem <0>spezifizierten regulären Ausdruck</0> entsprechen",
"example_upstream_regular": "regulärer DNS (über UDP)",
"example_upstream_dot": "verschlüsseltes <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a>",
"example_upstream_doh": "verschlüsseltes <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "Sie können <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS-Stempel</a> für <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> oder <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> Resolver benutzen.",
"example_upstream_dot": "verschlüsseltes <0>DNS-over-TLS</0>",
"example_upstream_doh": "verschlüsseltes <0>DNS_over_HTTPS</0>",
"example_upstream_sdns": "Sie können <0>DNS-Stempel</0> für <1>DNSCrypt</1> oder <2>DNS-over-HTTPS</2> Resolver benutzen",
"example_upstream_tcp": "regulärer DNS (über TCP)",
"all_lists_up_to_date_toast": "Alle Listen sind bereits auf dem neuesten Stand",
"updated_upstream_dns_toast": "Upstream-DNS-Server wurden aktualisiert",
"dns_test_ok_toast": "Angegebene DNS-Server arbeiten ordnungsgemäß",
"dns_test_not_ok_toast": "Server \"{{key}}\": konnte nicht verwendet werden, bitte überprüfen Sie die korrekte Schreibweise",
"unblock_btn": "Entblocken",
"block_btn": "Blockieren",
"unblock": "Entsperren",
"block": "Blockieren",
"time_table_header": "Zeit",
"date": "Datum",
"domain_name_table_header": "Domainname",
"domain_or_client": "Domain oder Client",
"type_table_header": "Typ",
"response_table_header": "Antwort",
"response_code": "Antwortcode",
"client_table_header": "Client",
"empty_response_status": "Leer",
"show_all_filter_type": "Alle anzeigen",
@@ -194,6 +212,7 @@
"query_log_filtered": "Gefiltert nach {{filter}}",
"query_log_confirm_clear": "Möchten Sie wirklich das Abfrageprotokoll vollständig löschen?",
"query_log_cleared": "Das Abfrageprotokoll wurde erfolgreich gelöscht",
"query_log_updated": "Das Abfrageprotokoll wurde erfolgreich aktualisiert",
"query_log_clear": "Abfrageprotokolle leeren",
"query_log_retention": "Abfrageprotokolle aufbewahren",
"query_log_enable": "Protokoll aktivieren",
@@ -211,6 +230,9 @@
"custom_ip": "Benutzerdefinierte IP",
"blocking_ipv4": "IPv4-Sperren",
"blocking_ipv6": "IPv6-Sperren",
"dns_over_https": "DNS-over-HTTPS (DNS-Abrage über HTTPS)",
"dns_over_tls": "DNS-over-TLS (DNS-Abrage über TLS)",
"plain_dns": "Einfaches DNS",
"form_enter_rate_limit": "Begrenzungswert eingeben",
"rate_limit": "Begrenzungswert",
"edns_enable": "EDNS Client Subnetz aktivieren",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Null-IP: Antworten mit Null-IP-Adresse (0.0.0.0.0 für A; :: für AAAA)",
"blocking_mode_custom_ip": "Benutzerdefinierte IP: Mit einer manuell eingestellten IP-Adresse antworten",
"upstream_dns_client_desc": "Wenn Sie dieses Feld leer lassen, verwendet AdGuard Home die Server, die in den <0>DNS-Einstellungen</0> konfiguriert sind.",
"tracker_source": "Tracker-Quelle",
"source_label": "Quelle",
"found_in_known_domain_db": "In der Datenbank der bekannten Domains gefunden.",
"category_label": "Kategorie",
"rule_label": "Regel",
"list_label": "Liste",
"unknown_filter": "Unbekannter Filter {{filterId}}",
"known_tracker": "Bekannte Tracker",
"install_welcome_title": "Willkommen bei AdGuard Home!",
"install_welcome_desc": "AdGuard Home ist ein netzwerkweiter Werbung- und Tracking sperrender DNS-Server. Sein Zweck ist es, Ihnen die Kontrolle über Ihr gesamtes Netzwerk und alle Ihre Geräte zu ermöglichen, und es ist nicht erforderlich, eine clientseitige Anwendung zu verwenden.",
"install_settings_title": "Admin Weboberfläche",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "Öffnen Sie die Einstellungen für Ihren Router. In der Regel können Sie von Ihrem Browser aus über eine URL (wie http://192.168.0.1/ oder http://192.168.1.1/) darauf zugreifen. Möglicherweise werden Sie aufgefordert, das Passwort einzugeben. Wenn Sie sich nicht mehr daran erinnern, können Sie das Passwort oft durch Drücken einer Taste auf dem Router selbst zurücksetzen. Einige Router benötigen eine bestimmte Anwendung, die in diesem Fall bereits auf Ihrem Computer/Telefon installiert sein sollte.",
"install_devices_router_list_2": "DHCP/DNS-Einstellungen suchen. Suchen Sie nach den DNS-Buchstaben neben einem Feld, das zwei oder drei Zahlensätze erlaubt, die jeweils in vier Gruppen von ein bis drei Ziffern unterteilt sind.",
"install_devices_router_list_3": "Geben Sie dort Ihre AdGuard Home Server-Adressen ein.",
"install_devices_router_list_4": "Sie können auf einigen Routern keine beliebigen DNS-Server festlegen. In diesem Fall kann es hilfreich sein, dass Sie AdGuard Home als DHCP-Server festlegen. Andernfalls sollten Sie nach einer Bedienungsanleitung zum Anpassen des DNS-Server für Ihr Router-Modell suchen.",
"install_devices_router_list_4": "Sie können auf einigen Routern keine beliebigen DNS-Server festlegen. In diesem Fall kann es hilfreich sein, dass Sie AdGuard Home als <0>DHCP-Server</0> festlegen. Andernfalls sollten Sie nach einer Bedienungsanleitung zum Anpassen des DNS-Server für Ihr Router-Modell suchen.",
"install_devices_windows_list_1": "Öffnen Sie die Systemsteuerung über das Startmenü oder die Windows-Suche.",
"install_devices_windows_list_2": "Öffnen Sie die Kategorie „Netzwerk und Internet” und dann „Netzwerk- und Freigabecenter”.",
"install_devices_windows_list_3": "Suchen Sie auf der linken Seite des Bildschirms nach „Adaptereinstellungen ändern” und klicken Sie darauf.",
@@ -346,6 +370,7 @@
"form_enter_id": "Kennung eingeben",
"form_add_id": "Kennung hinzufügen",
"form_client_name": "Clientnamen eingeben",
"name": "Name",
"client_global_settings": "Allgemeine Einstellungen nutzen",
"client_deleted": "Client „{{key}}” erfolgreich entfernt",
"client_added": "Client „{{key}}” erfolgreich hinzugefügt",
@@ -445,6 +470,7 @@
"location": "Ort",
"orgname": "Name der Organisation",
"netname": "Netzwerkname",
"network": "Netzwerk",
"descr": "Beschreibung",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Erfahren Sie mehr</0> über die Erstellung eigener Hosts-Listen.",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} Liste aktualisiert",
"list_updated_plural": "{{count}} Listen aktualisiert",
"dnssec_enable": "DNSSEC aktivieren",
"dnssec_enable_desc": "DNSSEC-Flag in den ausgehenden DNS-Abfragen mitsenden und das Ergebnis überprüfen (DNSSEC-fähiger Resolver erforderlich)"
}
"dnssec_enable_desc": "DNSSEC-Flag in den ausgehenden DNS-Abfragen mitsenden und das Ergebnis überprüfen (DNSSEC-fähiger Resolver erforderlich)",
"validated_with_dnssec": "Bestätigt mit DNSSEC",
"show_all_responses": "Alle Antworten",
"show_blocked_responses": "Gesperrt",
"show_whitelisted_responses": "Auf der Positivliste",
"show_processed_responses": "Verarbeitet",
"blocked_safebrowsing": "Durch Internetsicherheit gesperrt",
"blocked_adult_websites": "Gesperrte jugendgefährdende Webseiten",
"blocked_threats": "Gesperrte Bedrohungen",
"allowed": "Zugelassen",
"filtered": "Gefiltert",
"rewritten": "Umgeschrieben",
"safe_search": "Sichere Suche",
"blocklist": "Sperrliste",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "You can specify DNS upstream <0>for the specific domain(s)</0>",
"upstream_parallel": "Use parallel requests to speed up resolving by simultaneously querying all upstream servers",
"parallel_requests": "Parallel requests",
"load_balancing": "Load-balancing",
"load_balancing_desc": "Query one server at a time. AdGuard Home will use the weighted random algorithm to pick the server so that the fastest server will be used more often.",
"bootstrap_dns": "Bootstrap DNS servers",
"bootstrap_dns_desc": "Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams.",
"check_dhcp_servers": "Check for DHCP servers",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Select DHCP interface",
"dhcp_hardware_address": "Hardware address",
"dhcp_ip_addresses": "IP addresses",
"ip": "IP",
"dhcp_table_hostname": "Hostname",
"dhcp_table_expires": "Expires",
"dhcp_warning": "If you want to enable DHCP server anyway, make sure that there is no other active DHCP server in your network. Otherwise, it can break the Internet for connected devices!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "No DHCP static leases found",
"dhcp_add_static_lease": "Add static lease",
"dhcp_reset": "Are you sure you want to reset DHCP config?",
"country": "Country",
"city": "City",
"delete_confirm": "Are you sure you want to delete \"{{key}}\"?",
"form_enter_hostname": "Enter hostname",
"error_details": "Error details",
"response_details": "Response details",
"request_details": "Request details",
"client_details": "Client details",
"details": "Details",
"back": "Back",
"dashboard": "Dashboard",
"settings": "Settings",
"filters": "Filters",
"filter": "Filter",
"query_log": "Query Log",
"compact": "Compact",
"nothing_found": "Nothing found",
"faq": "FAQ",
"version": "Version",
"address": "address",
"address": "Address",
"protocol": "Protocol",
"on": "ON",
"off": "OFF",
"copyright": "Copyright",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Rules count",
"last_time_updated_table_header": "Last time updated",
"actions_table_header": "Actions",
"request_table_header": "Request",
"edit_table_action": "Edit",
"delete_table_action": "Delete",
"elapsed": "Elapsed",
"filters_and_hosts_hint": "AdGuard Home understands basic adblock rules and hosts files syntax.",
"no_blocklist_added": "No blocklists added",
"no_whitelist_added": "No allowlists added",
@@ -147,6 +162,8 @@
"new_allowlist": "New allowlist",
"edit_blocklist": "Edit blocklist",
"edit_allowlist": "Edit allowlist",
"choose_blocklist": "Choose blocklists",
"choose_allowlist": "Choose allowlists",
"enter_valid_blocklist": "Enter a valid URL to the blocklist.",
"enter_valid_allowlist": "Enter a valid URL to the allowlist.",
"form_error_url_format": "Invalid URL format",
@@ -170,12 +187,15 @@
"updated_upstream_dns_toast": "Updated the upstream DNS servers",
"dns_test_ok_toast": "Specified DNS servers are working correctly",
"dns_test_not_ok_toast": "Server \"{{key}}\": could not be used, please check that you've written it correctly",
"unblock_btn": "Unblock",
"block_btn": "Block",
"unblock": "Unblock",
"block": "Block",
"time_table_header": "Time",
"date": "Date",
"domain_name_table_header": "Domain name",
"domain_or_client": "Domain or client",
"type_table_header": "Type",
"response_table_header": "Response",
"response_code": "Response code",
"client_table_header": "Client",
"empty_response_status": "Empty",
"show_all_filter_type": "Show all",
@@ -194,6 +214,7 @@
"query_log_filtered": "Filtered by {{filter}}",
"query_log_confirm_clear": "Are you sure you want to clear the entire query log?",
"query_log_cleared": "The query log has been successfully cleared",
"query_log_updated": "The query log has been successfully updated",
"query_log_clear": "Clear query logs",
"query_log_retention": "Query logs retention",
"query_log_enable": "Enable log",
@@ -204,6 +225,8 @@
"anonymize_client_ip": "Anonymize client IP",
"anonymize_client_ip_desc": "Don't save the full IP address of the client in logs and statistics",
"dns_config": "DNS server configuration",
"dns_cache_config": "DNS cache configuration",
"dns_cache_config_desc": "Here you can configure DNS cache",
"blocking_mode": "Blocking mode",
"default": "Default",
"nxdomain": "NXDOMAIN",
@@ -211,6 +234,9 @@
"custom_ip": "Custom IP",
"blocking_ipv4": "Blocking IPv4",
"blocking_ipv6": "Blocking IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "Plain DNS",
"form_enter_rate_limit": "Enter rate limit",
"rate_limit": "Rate limit",
"edns_enable": "Enable EDNS Client Subnet",
@@ -223,12 +249,14 @@
"blocking_mode_null_ip": "Null IP: Respond with zero IP address (0.0.0.0 for A; :: for AAAA)",
"blocking_mode_custom_ip": "Custom IP: Respond with a manually set IP address",
"upstream_dns_client_desc": "If you keep this field empty, AdGuard Home will use the servers configured in the <0>DNS settings</0>.",
"tracker_source": "Tracker source",
"source_label": "Source",
"found_in_known_domain_db": "Found in the known domains database.",
"category_label": "Category",
"rule_label": "Rule",
"list_label": "List",
"unknown_filter": "Unknown filter {{filterId}}",
"known_tracker": "Known tracker",
"install_welcome_title": "Welcome to AdGuard Home!",
"install_welcome_desc": "AdGuard Home is a network-wide ad-and-tracker blocking DNS server. Its purpose is to let you control your entire network and all your devices, and it does not require using a client-side program.",
"install_settings_title": "Admin Web Interface",
@@ -257,7 +285,7 @@
"install_devices_router_list_1": "Open the preferences for your router. Usually, you can access it from your browser via a URL (like http://192.168.0.1/ or http://192.168.1.1/). You may be asked to enter the password. If you don't remember it, you can often reset the password by pressing a button on the router itself. Some routers require a specific application, which in that case should be already installed on your computer/phone.",
"install_devices_router_list_2": "Find the DHCP/DNS settings. Look for the DNS letters next to a field which allows two or three sets of numbers, each broken into four groups of one to three digits.",
"install_devices_router_list_3": "Enter your AdGuard Home server addresses there.",
"install_devices_router_list_4": "You can't set a custom DNS server on some types of routers. In this case it may help if you set up AdGuard Home as a <a href='#dhcp'>DHCP server</a>. Otherwise, you should search for the manual on how to customize DNS servers for your particular router model.",
"install_devices_router_list_4": "You can't set a custom DNS server on some types of routers. In this case it may help if you set up AdGuard Home as a <0>DHCP server</0>. Otherwise, you should search for the manual on how to customize DNS servers for your particular router model.",
"install_devices_windows_list_1": "Open Control Panel through Start menu or Windows search.",
"install_devices_windows_list_2": "Go to Network and Internet category and then to Network and Sharing Center.",
"install_devices_windows_list_3": "On the left side of the screen find Change adapter settings and click on it.",
@@ -346,6 +374,7 @@
"form_enter_id": "Enter identifier",
"form_add_id": "Add identifier",
"form_client_name": "Enter client name",
"name": "Name",
"client_global_settings": "Use global settings",
"client_deleted": "Client \"{{key}}\" successfully deleted",
"client_added": "Client \"{{key}}\" successfully added",
@@ -420,6 +449,7 @@
"domain": "Domain",
"answer": "Answer",
"filter_added_successfully": "The list has been successfully added",
"filter_removed_successfully": "The list has been successfully removed",
"filter_updated": "The list has been successfully updated",
"statistics_configuration": "Statistics configuration",
"statistics_retention": "Statistics retention",
@@ -445,6 +475,7 @@
"location": "Location",
"orgname": "Organization name",
"netname": "Network name",
"network": "Network",
"descr": "Description",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Learn more</0> about creating your own hosts lists.",
@@ -453,6 +484,10 @@
"domain_desc": "Enter the domain name or wildcard you want to be rewritten.",
"example_rewrite_domain": "rewrite responses for this domain name only.",
"example_rewrite_wildcard": "rewrite responses for all <0>example.org</0> subdomains.",
"rewrite_ip_address": "IP address: use this IP in an A or AAAA response",
"rewrite_domain_name": "Domain name: add a CNAME record",
"rewrite_A": "<0>A</0>: special value, keep <0>A</0> records from the upstream",
"rewrite_AAAA": "<0>AAAA</0>: special value, keep <0>AAAA</0> records from the upstream",
"disable_ipv6": "Disable IPv6",
"disable_ipv6_desc": "If this feature is enabled, all DNS queries for IPv6 addresses (type AAAA) will be dropped.",
"fastest_addr": "Fastest IP address",
@@ -468,6 +503,8 @@
"check": "Check",
"form_enter_host": "Enter a host name",
"filtered_custom_rules": "Filtered by Custom filtering rules",
"choose_from_list": "Choose from the list",
"add_custom_list": "Add a custom list",
"host_whitelisted": "The host is whitelisted",
"check_ip": "IP addresses: {{ip}}",
"check_cname": "CNAME: {{cname}}",
@@ -489,5 +526,39 @@
"list_updated": "{{count}} list updated",
"list_updated_plural": "{{count}} lists updated",
"dnssec_enable": "Enable DNSSEC",
"dnssec_enable_desc": "Set DNSSEC flag in the outcoming DNS queries and check the result (DNSSEC-enabled resolver is required)"
"dnssec_enable_desc": "Set DNSSEC flag in the outcoming DNS queries and check the result (DNSSEC-enabled resolver is required)",
"validated_with_dnssec": "Validated with DNSSEC",
"show_all_responses": "All responses",
"show_blocked_responses": "Blocked",
"show_whitelisted_responses": "Whitelisted",
"show_processed_responses": "Processed",
"blocked_safebrowsing": "Blocked by Safebrowsing",
"blocked_adult_websites": "Blocked Adult Websites",
"blocked_threats": "Blocked Threats",
"allowed": "Allowed",
"filtered": "Filtered",
"rewritten": "Rewritten",
"safe_search": "Safe search",
"blocklist": "Blocklist",
"milliseconds_abbreviation": "ms",
"dnssec_enable_desc": "Set DNSSEC flag in the outcoming DNS queries and check the result (DNSSEC-enabled resolver is required)",
"cache_size": "Cache size",
"cache_size_desc": "DNS cache size (in bytes)",
"cache_ttl_min_override": "Override minimum TTL",
"cache_ttl_max_override": "Override maximum TTL",
"enter_cache_size": "Enter cache size",
"enter_cache_ttl_min_override": "Enter minimum TTL",
"enter_cache_ttl_max_override": "Enter maximum TTL",
"cache_ttl_min_override_desc": "Override TTL value (minimum) received from upstream server. This value can't larger than 3600 (1 hour)",
"cache_ttl_max_override_desc": "Override TTL value (maximum) received from upstream server",
"min_exceeds_max_value": "Minimum value exceeds maximum value",
"value_not_larger_than": "Value can't be larger than {{maximum}}",
"filter_category_general": "General",
"filter_category_security": "Security",
"filter_category_regional": "Regional",
"filter_category_other": "Other",
"filter_category_general_desc": "Lists that block tracking and advertising on most of the devices",
"filter_category_security_desc": "Lists that specialize on blocking malware, phishing or scam domains",
"filter_category_regional_desc": "Lists that focus on regional ads and tracking servers",
"filter_category_other_desc": "Other blocklists"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "puedes especificar el DNS de subida <0>para un dominio específico</0>",
"upstream_parallel": "Usar peticiones paralelas para acelerar la resolución al consultar simultáneamente a todos los servidores de subida",
"parallel_requests": "Peticiones paralelas",
"load_balancing": "Balanceo de carga",
"load_balancing_desc": "Consulta un servidor a la vez. AdGuard Home utilizará el algoritmo aleatorio ponderado para elegir el servidor más rápido y sea utilizado con más frecuencia.",
"bootstrap_dns": "Servidores DNS de arranque",
"bootstrap_dns_desc": "Los servidores DNS de arranque se utilizan para resolver las direcciones IP de los resolutores DoH/DoT que usted especifique como DNS de subida.",
"check_dhcp_servers": "Comprobar si hay servidores DHCP",
@@ -10,7 +12,7 @@
"enabled_dhcp": "Servidor DHCP habilitado",
"disabled_dhcp": "Servidor DHCP deshabilitado",
"dhcp_title": "Servidor DHCP (experimental)",
"dhcp_description": "Si tu router no proporciona la configuración DHCP, puede utilizar el propio servidor DHCP incorporado de AdGuard.",
"dhcp_description": "Si tu router no proporciona la configuración DHCP, puedes utilizar el propio servidor DHCP incorporado de AdGuard.",
"dhcp_enable": "Habilitar servidor DHCP",
"dhcp_disable": "Deshabilitar servidor DHCP",
"dhcp_not_found": "Es seguro habilitar el servidor DHCP incorporado. No se ha encontrado ningún servidor DHCP activo en la red, sin embargo le recomendamos que lo vuelva a comprobar manualmente, ya que nuestra prueba automática no ofrece actualmente una garantía del 100 %.",
@@ -37,29 +39,40 @@
"dhcp_interface_select": "Seleccione la interfaz DHCP",
"dhcp_hardware_address": "Dirección MAC",
"dhcp_ip_addresses": "Direcciones IP",
"ip": "IP",
"dhcp_table_hostname": "Nombre del host",
"dhcp_table_expires": "Expira",
"dhcp_warning": "Si de todos modos desea habilitar el servidor DHCP, asegúrese de que no hay otro servidor DHCP activo en tu red. ¡De lo contrario, puede dejar sin Internet a los dispositivos conectados!",
"dhcp_warning": "Si de todos modos deseas habilitar el servidor DHCP, asegúrate de que no hay otro servidor DHCP activo en tu red. ¡De lo contrario, puedes dejar sin Internet a los dispositivos conectados!",
"dhcp_error": "No pudimos determinar si hay otro servidor DHCP en la red.",
"dhcp_static_ip_error": "Para poder utilizar el servidor DHCP se debe establecer una dirección IP estática. No hemos podido determinar si esta interfaz de red está configurada utilizando una dirección IP estática. Por favor establezca una dirección IP estática manualmente.",
"dhcp_dynamic_ip_found": "Tu sistema utiliza la configuración de dirección IP dinámica para la interfaz <0>{{interfaceName}}</0>. Para poder utilizar el servidor DHCP se debe establecer una dirección IP estática. Tu dirección IP actual es <0>{{ipAddress}}</0>. Si presiona el botón Habilitar servidor DHCP, estableceremos automáticamente esta dirección IP como estática.",
"dhcp_dynamic_ip_found": "Tu sistema utiliza la configuración de dirección IP dinámica para la interfaz <0>{{interfaceName}}</0>. Para poder utilizar el servidor DHCP se debe establecer una dirección IP estática. Tu dirección IP actual es <0>{{ipAddress}}</0>. Si presionas el botón Habilitar servidor DHCP, estableceremos automáticamente esta dirección IP como estática.",
"dhcp_lease_added": "Asignación estática \"{{key}}\" añadido correctamente",
"dhcp_lease_deleted": "Asignación estática \"{{key}}\" eliminado correctamente",
"dhcp_new_static_lease": "Nueva asignación estática",
"dhcp_static_leases_not_found": "No se han encontrado asignaciones DHCP estáticas",
"dhcp_add_static_lease": "Añadir asignación estática",
"dhcp_reset": "¿Está seguro de que desea restablecer la configuración DHCP?",
"country": "País",
"city": "Ciudad",
"delete_confirm": "¿Está seguro de que desea eliminar \"{{key}}\"?",
"form_enter_hostname": "Ingresa el nombre del host",
"error_details": "Detalles del error",
"response_details": "Detalles de la respuesta",
"request_details": "Detalles de la petición",
"client_details": "Detalles del cliente",
"details": "Detalles",
"back": "Atrás",
"dashboard": "Panel de control",
"settings": "Configuración",
"filters": "Filtros",
"filter": "Filtro",
"query_log": "Registro de consultas",
"compact": "Compacto",
"nothing_found": "No se ha encontrado nada",
"faq": "Preguntas frecuentes",
"version": "Versión",
"address": "dirección",
"address": "Dirección",
"protocol": "Protocolo",
"on": "Activo",
"off": "Inactivo",
"copyright": "Copyright",
@@ -85,7 +98,7 @@
"top_clients": "Clientes más frecuentes",
"no_clients_found": "No se han encontrado clientes",
"general_statistics": "Estadísticas generales",
"number_of_dns_query_days": "Número de consultas DNS procesadas durante los últimos {{count}} días",
"number_of_dns_query_days": "Número de consultas DNS procesadas durante el último {{count}} día",
"number_of_dns_query_days_plural": "Número de consultas DNS procesadas durante los últimos {{count}} días",
"number_of_dns_query_24_hours": "Número de consultas DNS procesadas durante las últimas 24 horas",
"number_of_dns_query_blocked_24_hours": "Número de peticiones DNS bloqueadas por los filtros y listas de bloqueo de hosts",
@@ -96,7 +109,7 @@
"average_processing_time": "Tiempo promedio de procesamiento",
"average_processing_time_hint": "Tiempo promedio en milisegundos al procesar una petición DNS",
"block_domain_use_filters_and_hosts": "Bloquear dominios usando filtros y archivos hosts",
"filters_block_toggle_hint": "Puede configurar las reglas de bloqueo en la configuración de <a href='#filters'>filtros</a>.",
"filters_block_toggle_hint": "Puedes configurar las reglas de bloqueo en la configuración de <a href='#filters'>filtros</a>.",
"use_adguard_browsing_sec": "Usar el servicio web de seguridad de navegación de AdGuard",
"use_adguard_browsing_sec_hint": "AdGuard Home comprobará si el dominio está en la lista negra del servicio web de seguridad de navegación. Utilizará la API de búsqueda amigable con la privacidad para realizar la comprobación: solo se envía al servidor un prefijo corto del nombre de dominio con hash SHA256.",
"use_adguard_parental": "Usar el control parental de AdGuard",
@@ -114,14 +127,14 @@
"encryption_settings": "Configuración de cifrado",
"dhcp_settings": "Configuración DHCP",
"upstream_dns": "Servidores DNS de subida",
"upstream_dns_hint": "Si mantiene este campo vacío, AdGuard Home utilizará <a href='https://www.quad9.net/' target='_blank'>Quad9</a> como DNS de subida.",
"upstream_dns_hint": "Si se mantiene este campo vacío, AdGuard Home utilizará <a href='https://www.quad9.net/' target='_blank'>Quad9</a> como DNS de subida.",
"test_upstream_btn": "Probar DNS de subida",
"upstreams": "DNS de subida",
"apply_btn": "Aplicar",
"disabled_filtering_toast": "Filtrado deshabilitado",
"enabled_filtering_toast": "Filtrado habilitado",
"disabled_safe_browsing_toast": "Búsqueda segura deshabilitada",
"enabled_safe_browsing_toast": "Búsqueda segura habilitada",
"disabled_safe_browsing_toast": "Navegación segura deshabilitada",
"enabled_safe_browsing_toast": "Navegación segura habilitada",
"disabled_parental_toast": "Control parental deshabilitado",
"enabled_parental_toast": "Control parental habilitado",
"disabled_safe_search_toast": "Búsqueda segura deshabilitada",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Número de reglas",
"last_time_updated_table_header": "Última actualización",
"actions_table_header": "Acciones",
"request_table_header": "Petición",
"edit_table_action": "Editar",
"delete_table_action": "Eliminar",
"elapsed": "Transcurrido",
"filters_and_hosts_hint": "AdGuard Home entiende las reglas básicas de bloqueo y la sintaxis de los archivos hosts.",
"no_blocklist_added": "No se han añadido listas de bloqueo",
"no_whitelist_added": "No se han añadido listas de permitido",
@@ -169,13 +184,16 @@
"all_lists_up_to_date_toast": "Todas las listas ya están actualizadas",
"updated_upstream_dns_toast": "Servidores DNS de subida actualizados",
"dns_test_ok_toast": "Los servidores DNS especificados funcionan correctamente",
"dns_test_not_ok_toast": "Servidor \"{{key}}\": no se puede utilizar, por favor revise si lo ha escrito correctamente",
"unblock_btn": "Desbloquear",
"block_btn": "Bloquear",
"dns_test_not_ok_toast": "Servidor \"{{key}}\": no se puede utilizar, por favor revisa si lo has escrito correctamente",
"unblock": "Desbloquear",
"block": "Bloquear",
"time_table_header": "Hora",
"date": "Fecha",
"domain_name_table_header": "Nombre del dominio",
"domain_or_client": "Dominio o cliente",
"type_table_header": "Tipo",
"response_table_header": "Respuesta",
"response_code": "Código de respuesta",
"client_table_header": "Cliente",
"empty_response_status": "Vacío",
"show_all_filter_type": "Mostrar todo",
@@ -194,6 +212,7 @@
"query_log_filtered": "Filtrado por {{filter}}",
"query_log_confirm_clear": "¿Está seguro de que desea borrar todo el registro de consultas?",
"query_log_cleared": "El registro de consultas se ha borrado correctamente",
"query_log_updated": "El registro de consultas se ha actualizado correctamente",
"query_log_clear": "Borrar registros de consultas",
"query_log_retention": "Retención de registros de consultas",
"query_log_enable": "Habilitar registro",
@@ -211,6 +230,9 @@
"custom_ip": "IP personalizada",
"blocking_ipv4": "Bloqueo de IPv4",
"blocking_ipv6": "Bloqueo de IPv6",
"dns_over_https": "DNS mediante HTTPS",
"dns_over_tls": "DNS mediante TLS",
"plain_dns": "DNS simple",
"form_enter_rate_limit": "Ingresa el límite de cantidad",
"rate_limit": "Límite de cantidad",
"edns_enable": "Habilitar subred de cliente EDNS",
@@ -222,13 +244,15 @@
"blocking_mode_nxdomain": "NXDOMAIN: Responde con el código NXDOMAIN",
"blocking_mode_null_ip": "IP nulo: Responde con dirección IP cero (0.0.0.0 para A; :: para AAAA)",
"blocking_mode_custom_ip": "IP personalizada: Responde con una dirección IP establecida manualmente",
"upstream_dns_client_desc": "Si mantiene este campo vacío, AdGuard Home utilizará los servidores configurados en la <0>configuración del DNS</0>.",
"upstream_dns_client_desc": "Si se mantiene este campo vacío, AdGuard Home utilizará los servidores configurados en la <0>configuración del DNS</0>.",
"tracker_source": "Fuente del rastreador",
"source_label": "Fuente",
"found_in_known_domain_db": "Encontrado en la base de datos de dominios conocidos.",
"category_label": "Categoría",
"rule_label": "Regla",
"list_label": "Lista",
"unknown_filter": "Filtro desconocido {{filterId}}",
"known_tracker": "Rastreador conocido",
"install_welcome_title": "¡Bienvenido a AdGuard Home!",
"install_welcome_desc": "AdGuard Home es un servidor DNS para bloqueo de anuncios y rastreadores a nivel de red. Su propósito es permitirte controlar toda tu red y todos tus dispositivos, y no requiere el uso de un programa del lado del cliente.",
"install_settings_title": "Interfaz web de administración",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "Abre las preferencias de tu router. Por lo general, puedes acceder a él desde tu navegador a través de una URL (como http://192.168.0.1/ o http://192.168.1.1/). Es posible que se te pida que ingreses la contraseña. Si no lo recuerdas, a menudo puedes restablecer la contraseña presionando un botón en el router. Algunos routers requieren una aplicación específica, que en ese caso ya debería estar instalada en tu computadora/teléfono.",
"install_devices_router_list_2": "Busca la configuración de DHCP/DNS. Busca las letras DNS junto a un campo que permita ingresar dos o tres grupos de números, cada uno dividido en cuatro grupos de uno a tres dígitos.",
"install_devices_router_list_3": "Ingresa las direcciones de tu servidor AdGuard Home allí.",
"install_devices_router_list_4": "No se puede configurar un servidor DNS personalizado en algunos tipos de routers. En este caso puede ayudar si configuras AdGuard Home como un servidor DHCP. De lo contrario, deberías buscar el manual sobre cómo personalizar los servidores DNS para tu modelo de router en particular.",
"install_devices_router_list_4": "No se puede configurar un servidor DNS personalizado en algunos tipos de routers. En este caso puede ayudar si configuras AdGuard Home como un <0>servidor DHCP</0>. De lo contrario, deberías buscar el manual sobre cómo personalizar los servidores DNS para tu modelo de router en particular.",
"install_devices_windows_list_1": "Abre el Panel de control a través del menú Inicio o en el buscador de Windows.",
"install_devices_windows_list_2": "Ve a la categoría Redes e Internet, luego a Centro de redes y recursos compartidos.",
"install_devices_windows_list_3": "En el lado izquierdo de la pantalla, busca Cambiar configuración del adaptador y luego haz clic en él.",
@@ -346,6 +370,7 @@
"form_enter_id": "Ingresa el identificador",
"form_add_id": "Añadir identificador",
"form_client_name": "Ingresa el nombre del cliente",
"name": "Nombre",
"client_global_settings": "Usar configuración global",
"client_deleted": "Cliente \"{{key}}\" eliminado correctamente",
"client_added": "Cliente \"{{key}}\" añadido correctamente",
@@ -356,7 +381,7 @@
"auto_clients_title": "Clientes (activos)",
"auto_clients_desc": "Datos de los clientes que utilizan AdGuard Home, pero no se almacenan en la configuración",
"access_title": "Configuración de acceso",
"access_desc": "Aquí puede configurar las reglas de acceso para el servidor DNS de AdGuard Home.",
"access_desc": "Aquí puedes configurar las reglas de acceso para el servidor DNS de AdGuard Home.",
"access_allowed_title": "Clientes permitidos",
"access_allowed_desc": "Lista de CIDR o direcciones IP. Si está configurado, AdGuard Home solo aceptará peticiones de estas direcciones IP.",
"access_disallowed_title": "Clientes no permitidos",
@@ -382,7 +407,7 @@
"setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0> soporta <1>DNS mediante HTTPS</1>.",
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0> soporta <1>DNS mediante HTTPS</1>.",
"setup_dns_privacy_other_5": "Encontrará más implementaciones <0>aquí</0> y <1>aquí</1>.",
"setup_dns_notice": "Para utilizar <1>DNS mediante HTTPS</1> o <1>DNS mediante TLS</1>, debe <0>configurar el cifrado</0> en la configuración de AdGuard Home.",
"setup_dns_notice": "Para utilizar <1>DNS mediante HTTPS</1> o <1>DNS mediante TLS</1>, debes <0>configurar el cifrado</0> en la configuración de AdGuard Home.",
"rewrite_added": "Reescritura DNS para \"{{key}}\" añadido correctamente",
"rewrite_deleted": "Reescritura DNS para \"{{key}}\" eliminado correctamente",
"rewrite_add": "Añadir reescritura DNS",
@@ -445,6 +470,7 @@
"location": "Ubicación",
"orgname": "Nombre de la organización",
"netname": "Nombre de la red",
"network": "Red",
"descr": "Descripción",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Más información</0> sobre cómo crear tus propias listas de hosts.",
@@ -456,12 +482,12 @@
"disable_ipv6": "Deshabilitar IPv6",
"disable_ipv6_desc": "Si esta función está habilitada, se eliminarán todas las consultas DNS para direcciones IPv6 (tipo AAAA).",
"fastest_addr": "Dirección IP más rápida",
"fastest_addr_desc": "Consulta todos los servidores DNS y devuelve la dirección IP más rápida de todas las respuestas",
"autofix_warning_text": "Si hace clic en \"Corregir\", AdGuard Home configurará tu sistema para utilizar el servidor DNS de AdGuard Home.",
"fastest_addr_desc": "Consulta todos los servidores DNS y devuelve la dirección IP más rápida de todas las respuestas. Esto ralentizará las consultas DNS, y se debe esperar las respuestas de todos los servidores DNS, pero mejora la conectividad general.",
"autofix_warning_text": "Si haces clic en \"Corregir\", AdGuard Home configurará tu sistema para utilizar el servidor DNS de AdGuard Home.",
"autofix_warning_list": "Realizará estas tareas: <0>Deshabilitar el sistema DNSStubListener</0> <0>Establecer la dirección del servidor DNS en 127.0.0.1</0> <0>Reemplazar el destino del enlace simbólico de /etc/resolv.conf por /run/systemd/resolve/resolv.conf</0> <0>Detener DNSStubListener (recargar el servicio systemd-resolved)</0>",
"autofix_warning_result": "Como resultado, todas las peticiones DNS de tu sistema serán procesadas por AdGuard Home de manera predeterminada.",
"tags_title": "Etiquetas",
"tags_desc": "Puede seleccionar las etiquetas que correspondan al cliente. Las etiquetas pueden ser incluidas en las reglas de filtrado y te permiten aplicarlas con mayor precisión. <0>Más información</0>",
"tags_desc": "Puedes seleccionar las etiquetas que correspondan al cliente. Las etiquetas pueden ser incluidas en las reglas de filtrado y te permiten aplicarlas con mayor precisión. <0>Más información</0>",
"form_select_tags": "Seleccione las etiquetas del cliente",
"check_title": "Comprobar filtrado",
"check_desc": "Comprueba si el nombre del host está siendo filtrado",
@@ -483,11 +509,25 @@
"static_ip_desc": "AdGuard Home es un servidor, por lo que necesita una dirección IP estática para funcionar correctamente. De lo contrario, en algún momento tu router puede asignar una dirección IP diferente a este dispositivo.",
"set_static_ip": "Establecer una dirección IP estática",
"install_static_ok": "¡Buenas noticias! La dirección IP estática ya está configurada",
"install_static_error": "AdGuard Home no puede configurarlo automáticamente para esta interfaz de red. Busque instrucciones sobre cómo hacer esto manualmente.",
"install_static_configure": "Hemos detectado que utiliza una dirección IP dinámica: <0>{{ip}}</0>. ¿Deseas usarla como tu dirección estática?",
"install_static_error": "AdGuard Home no puede configurarlo automáticamente para esta interfaz de red. Busca instrucciones sobre cómo hacer esto manualmente.",
"install_static_configure": "Hemos detectado que utilizas una dirección IP dinámica: <0>{{ip}}</0>. ¿Deseas usarla como tu dirección estática?",
"confirm_static_ip": "AdGuard Home configurará {{ip}} para ser tu dirección IP estática. ¿Desea continuar?",
"list_updated": "{{count}} lista actualizada",
"list_updated_plural": "{{count}} listas actualizadas",
"dnssec_enable": "Habilitar DNSSEC",
"dnssec_enable_desc": "Establece el indicador DNSSEC en las consultas DNS salientes y comprueba el resultado (se requiere un resolutor habilitado para DNSSEC)"
"dnssec_enable_desc": "Establece el indicador DNSSEC en las consultas DNS salientes y comprueba el resultado (se requiere un resolutor habilitado para DNSSEC)",
"validated_with_dnssec": "Validado con DNSSEC",
"show_all_responses": "Todas las respuestas",
"show_blocked_responses": "Bloqueado",
"show_whitelisted_responses": "En lista blanca",
"show_processed_responses": "Procesado",
"blocked_safebrowsing": "Bloqueado por navegación segura",
"blocked_adult_websites": "Sitios web para adultos bloqueado",
"blocked_threats": "Amenazas bloqueadas",
"allowed": "Permitido",
"filtered": "Filtrado",
"rewritten": "Reescrito",
"safe_search": "Búsqueda segura",
"blocklist": "Lista de bloqueo",
"milliseconds_abbreviation": "ms"
}

View File

@@ -37,6 +37,7 @@
"dhcp_interface_select": "رابط DHCP را انتخاب کنید",
"dhcp_hardware_address": "آدرس سخت افزار",
"dhcp_ip_addresses": "آدرس آی پی",
"ip": "IP",
"dhcp_table_hostname": "نام میزبان",
"dhcp_table_expires": "انقضاء",
"dhcp_warning": "اگر میخواهید DHCP سرور توکار را فعال کنید،مطمئن شوید DHCP سرور دیگری فعال نباشد.در غیر اینصورت،آن دسترسی به اینترنت را برای دستگاه های وصل شده قطع می کند!",
@@ -49,17 +50,25 @@
"dhcp_static_leases_not_found": "هیچ اجاره DHCP ایستا یافت نشد",
"dhcp_add_static_lease": "افزودن اجاره ایستا",
"dhcp_reset": "آیا میخواهید پیکربندی DHCP را ریست کنید؟",
"country": "کشور",
"city": "شهر",
"delete_confirm": "آیا میخواهید \"{{key}}\" را حذف کنید؟",
"form_enter_hostname": "نام میزبان را وارد کنید",
"error_details": "جزئیات خطا",
"response_details": "جزئیات پاسخ",
"request_details": "درخواست جزئیات",
"client_details": "جزئیات کلاینت",
"details": "جزئیات",
"back": "قبلی",
"dashboard": "داشبورد",
"settings": "تنظيمات",
"filters": "فيلترها",
"filter": "فیلتر",
"query_log": "جستار وقایع",
"faq": "پرسش و پاسخ",
"version": "نسخه",
"address": "آدرس",
"protocol": "پروتکل",
"on": "روشن",
"off": "خاموش",
"copyright": "حق مالکیت",
@@ -132,8 +141,10 @@
"rules_count_table_header": "تعداد دستور",
"last_time_updated_table_header": "زمان آخرین بروزرسانی",
"actions_table_header": "اقدامات",
"request_table_header": "درخواست",
"edit_table_action": "ويرايش",
"delete_table_action": "حذف",
"elapsed": "سپری شده",
"filters_and_hosts_hint": "AdGuard Home دستورات پایه مسدودساز تبلیغ و نحو فایل های میزبان را درک می کند.",
"no_blocklist_added": "به لیست سیاه اضافه نشد",
"no_whitelist_added": "به لیست مجاز اضافه نشد",
@@ -170,10 +181,12 @@
"updated_upstream_dns_toast": "سرورهای DNS جریان ارسالی بروز رسانی شده است",
"dns_test_ok_toast": "سرورهای DNS تعیین شده بدرستی کار می کنند",
"dns_test_not_ok_toast": "سرور \"{{key}}\": نمیتواند مورد استفاده قرار گیرد،لطفا بررسی کنید آن را بدرستی نوشته اید",
"unblock_btn": "باز کن",
"block_btn": "مسدود کن",
"unblock": "رفع انسداد",
"block": "مسدود کردن",
"time_table_header": "زمان",
"date": "تاریخ",
"domain_name_table_header": "نام دامنه",
"domain_or_client": "دامنه یا کلاینت",
"type_table_header": "نوع",
"response_table_header": "پاسخ",
"client_table_header": "کلاینت",
@@ -211,6 +224,8 @@
"custom_ip": "آی پی دستی",
"blocking_ipv4": "مسدودسازی IPv4",
"blocking_ipv6": "مسدودسازی IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"form_enter_rate_limit": "میزان محدودیت را وارد کنید",
"rate_limit": "میزان محدودیت",
"edns_enable": "فعالسازی زیرشبکه کلاینت EDNS",
@@ -229,6 +244,7 @@
"rule_label": "دستور",
"list_label": "لیست",
"unknown_filter": "فیلتر ناشناخته {{filterId}}",
"known_tracker": "ردیاب های شناخته شده",
"install_welcome_title": "به AdGuard Home خوش آمدید!",
"install_welcome_desc": "AdGuard Home یک شبکه گسترده و ردیاب و مسدوساز تبلیغ با سرور DNS است.هدف آن این است که به شما اجازه کنترل کل شبکه و همه دستگاه های شما را بدهد و آن نیازی به برنامه سمت-کاربر ندارد.",
"install_settings_title": "رابط وب آدمین",
@@ -346,6 +362,7 @@
"form_enter_id": "خطای احرازکننده",
"form_add_id": "افزودن احرازکننده",
"form_client_name": "نام کلاینت را وارد کنید",
"name": "نام",
"client_global_settings": "استفاده از تنظیمات سراسری",
"client_deleted": "کلاینت \"{{key}}\" را با موفقیت حذف کرد",
"client_added": "کلاینت \"{{key}}\" را با موفقیت اضافه کرد",
@@ -445,6 +462,7 @@
"location": "مکان",
"orgname": "نام سازمان",
"netname": "نام شبکه",
"network": "شبکه",
"descr": "توضيحات",
"whois": "هوئیز",
"filtering_rules_learn_more": "درباره ایجاد لیست سیاه میزبان برای خود <0>بیشتر بدانید</0>.",
@@ -489,5 +507,19 @@
"list_updated": "{{count}} لیست بروز رسانی شد",
"list_updated_plural": "{{count}} لیست بروز رسانی شد",
"dnssec_enable": "فعالسازی DNSSEC",
"dnssec_enable_desc": "تنظیم نشان DNSSEC در جستارهای حاصل DNS و بررسی نتیجه (تفکیک کننده DNSSEC-فعال شده نیاز است)"
"dnssec_enable_desc": "تنظیم نشان DNSSEC در جستارهای حاصل DNS و بررسی نتیجه (تفکیک کننده DNSSEC-فعال شده نیاز است)",
"validated_with_dnssec": "معتبر سازی با DNSSEC",
"show_all_responses": "همه پاسخ ها",
"show_blocked_responses": "مسدود شده",
"show_whitelisted_responses": "لیست سفید",
"show_processed_responses": "پردازش شده",
"blocked_safebrowsing": "بستن وب گردی اَمن",
"blocked_adult_websites": "وبسایت غیراخلاقی مسدود شده",
"blocked_threats": "تهدیدات مسدود شده",
"allowed": "اجازه داده شده",
"filtered": "فیلتر شده",
"rewritten": "بازنویسی شده",
"safe_search": "جستجوی اَمن",
"blocklist": "لیست سیاه",
"milliseconds_abbreviation": "هـ ثـ"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Vous pouvez spécifier un DNS en amont <0>pour un/des domaine(s) spécifique(s)</0>",
"upstream_parallel": "Utiliser des requêtes parallèles pour accélérer la résolution en requêtant simultanément tous les serveurs upstream",
"parallel_requests": "Demandes en parallèle",
"load_balancing": "Équilibrage de charge",
"load_balancing_desc": "Interroger un serveur à la fois. AdGuard Home utilisera lalgorithme aléatoire pondéré pour choisir le serveur afin que celui le plus rapide soit utilisé plus souvent.",
"bootstrap_dns": "Serveurs DNS d'amorçage",
"bootstrap_dns_desc": "Les serveurs DNS d'amorçage sont utilisés pour résoudre les adresses IP des résolveurs DoH/DoT que vous spécifiez comme upstream.",
"check_dhcp_servers": "Rechercher les serveurs DHCP",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Sélectionner l'interface du serveur DHCP",
"dhcp_hardware_address": "Adresse de la machine",
"dhcp_ip_addresses": "Adresses IP",
"ip": "IP",
"dhcp_table_hostname": "Nom de machine",
"dhcp_table_expires": "Expire le",
"dhcp_warning": "Si vous souhaitez tout de même activer le serveur DHCP, assurez-vous qu'il n'y a d'autre serveur DHCP actif sur votre réseau. Sinon, cela peut faire dysfonctionner Internet sur tous les appareils connectés au réseau !",
@@ -49,17 +52,25 @@
"dhcp_static_leases_not_found": "Aucun bail statique DHCP trouvé",
"dhcp_add_static_lease": "Ajoutez un bail statique",
"dhcp_reset": "Voulez-vous vraiment réinitialiser votre configuration DHCP ?",
"country": "Pays",
"city": "Ville",
"delete_confirm": "Voulez-vous vraiment supprimer \"{{key}}\" ?",
"form_enter_hostname": "Saisissez un nom d'hôte",
"error_details": "Détails des erreurs",
"response_details": "Détails de la réponse",
"request_details": "Demander des détails",
"client_details": "Détails du client",
"details": "Détails",
"back": "Retour",
"dashboard": "Tableau de bord",
"settings": "Paramètres",
"filters": "Filtres",
"filter": "Filtre",
"query_log": "Journal des requêtes",
"faq": "FAQ",
"version": "version",
"address": "addresse",
"address": "Addresse",
"protocol": "Protocole",
"on": "Activé",
"off": "Éteint",
"copyright": "Copyright",
@@ -132,8 +143,10 @@
"rules_count_table_header": "Nombre des règles",
"last_time_updated_table_header": "Dernière mise à jour",
"actions_table_header": "Actions",
"request_table_header": "Requête",
"edit_table_action": "Modifier",
"delete_table_action": "Supprimer",
"elapsed": "Écoulé",
"filters_and_hosts_hint": "AdGuard Home comprend les règles basiques de blocage ainsi que la syntaxe des fichiers hosts.",
"no_blocklist_added": "Aucune liste de blocage ajoutée",
"no_whitelist_added": "Aucune liste dautorisation ajoutée",
@@ -162,18 +175,20 @@
"example_comment_hash": "# Et comme ça aussi on peut laisser des commentaires",
"example_regex_meaning": "bloquer l'accés aux domaines correspondants à l'expression régulière spécifiée",
"example_upstream_regular": "DNS classique (au-dessus de UDP)",
"example_upstream_dot": "<a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-au-dessus-de-TLS</a> chiffré",
"example_upstream_doh": "<a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-au-dessus-de-HTTPS</a> chiffré",
"example_upstream_sdns": "vous pouvez utiliser <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> pour <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> ou les resolveurs <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-au-dessus-de-HTTPS</a>",
"example_upstream_dot": "<0>DNS-over-TLS</0> chiffré",
"example_upstream_doh": "<0>DNS-over-HTTPS</0> chiffré",
"example_upstream_sdns": "vous pouvez utiliser <0>DNS Stamps</0> pour <1>DNSCrypt</1> ou les resolveurs <2>DNS_over_HTTPS</2>",
"example_upstream_tcp": "DNS classique (au-dessus de TCP)",
"all_lists_up_to_date_toast": "Toutes les listes sont déjà à jour",
"updated_upstream_dns_toast": "Les serveurs DNS upstream sont mis à jour",
"dns_test_ok_toast": "Les serveurs DNS spécifiés fonctionnent correctement",
"dns_test_not_ok_toast": "Impossible d'utiliser le serveur \"{{key}}\": veuillez vérifier si le nom saisi est bien correct",
"unblock_btn": "Débloquer",
"block_btn": "Bloquer",
"unblock": "Débloquer",
"block": "Bloquer",
"time_table_header": "Temps",
"date": "Date",
"domain_name_table_header": "Nom de domaine",
"domain_or_client": "Domaine ou client",
"type_table_header": "Type",
"response_table_header": "Réponse",
"client_table_header": "Client",
@@ -211,6 +226,9 @@
"custom_ip": "IP personnalisée",
"blocking_ipv4": "Blocage IPv4",
"blocking_ipv6": "Blocage IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "DNS brut",
"form_enter_rate_limit": "Entrez la limite de taux",
"rate_limit": "Limite de taux",
"edns_enable": "Activer le sous-réseau du client EDNS",
@@ -229,6 +247,7 @@
"rule_label": "Règle",
"list_label": "Liste",
"unknown_filter": "Filtre inconnu {{filterId}}",
"known_tracker": "Pisteur connu",
"install_welcome_title": "Bienvenue sur AdGuard Home !",
"install_welcome_desc": "AdGuard Home est un seveur DNS pour bloquer les pubs et traceurs sur tout un réseau. Son but est de vous donner le contrôle sur l'ensemble de votre réseau et tous vos appareils sans programme côté client supplémentaire.",
"install_settings_title": "Interface web administrateur",
@@ -257,7 +276,7 @@
"install_devices_router_list_1": "Ouvrez les préférences de votre routeur. Normalement, vous pouvez y accéder depuis votre navigateur Web via une URL (exemple http://192.168.0.1/ ou http://192.168.1.1/). Vous devrez peut-être saisir le mot de passe. Si vous ne vous en rappelez plus, vous pouvez le réinitialiser en appuyant sur le bouton du routeur. Certains routeurs fonctionnent sous une application spécifique, qui devrait être déjà installée sur votre ordinateur/téléphone.",
"install_devices_router_list_2": "Trouvez les paramètres DHCP/DNS. Recherchez les lettres DNS près d'une zone qui permet la saisie de 2 ou 3 blocs de chiffres, chacun composé de 4 parties de 1 à 3 chiffres.",
"install_devices_router_list_3": "Saisissez vos adresses de serveur AdGuard Home ici.",
"install_devices_router_list_4": "Vous ne pouvez pas définir un serveur DNS personnalisé sur certains types de routeurs. Dans ce cas, cela peut être utile si vous configurez AdGuard Home en tant que serveur DHCP. Sinon, vous devez rechercher le manuel sur la façon de personnaliser les serveurs DNS pour votre modèle de routeur particulier.",
"install_devices_router_list_4": "Vous ne pouvez pas définir un serveur DNS personnalisé sur certains types de routeurs. Dans ce cas, cela peut être utile si vous configurez AdGuard Home en tant que <0>serveur DHCP</0>. Sinon, vous devez rechercher le manuel sur la façon de personnaliser les serveurs DNS pour votre modèle de routeur particulier.",
"install_devices_windows_list_1": "Ouvrez votre Panneau de configuration depuis le menu Démarrer ou la recherche Windows.",
"install_devices_windows_list_2": "Allez dans la catégorie Réseau et Internet et ensuite dans le Centre Réseau et Partage.",
"install_devices_windows_list_3": "Sur la partie gauche de l'écran, recherchez Modifier les paramètres de la carte et cliquez dessus.",
@@ -346,6 +365,7 @@
"form_enter_id": "Entrer identifiant",
"form_add_id": "Ajouter identifiant",
"form_client_name": "Saisissez le nom du client",
"name": "Nom",
"client_global_settings": "Utiliser les paramètres généraux",
"client_deleted": "Le client \"{{key}}\" a été supprimé avec succès",
"client_added": "Le client \"{{key}}\" a été ajouté",
@@ -361,6 +381,7 @@
"access_allowed_desc": "Une liste d'adresses IP ou CIDR. Si configuré, AdGuard Home acceptera uniquement les requêtes provenant de ces adresses IP.",
"access_disallowed_title": "Clients non autorisés",
"access_disallowed_desc": "Une liste d'adresses IP ou CIDR. Si configuré, AdGuard Home bloquera les requêtes provenant de ces adresses IP.",
"access_blocked_title": "Domaines interdits",
"access_blocked_desc": "Ne confondez pas ceci avec les filtres. AdGuard Home ignorera les requêtes DNS portant sur les domaines ci-dessous.",
"access_settings_saved": "Paramètres d'accès enregistrés avec succès",
"updates_checked": "Mises à jour vérifiées",
@@ -444,6 +465,7 @@
"location": "Localisation",
"orgname": "Nom de l'organisation",
"netname": "Nom du réseau",
"network": "Réseau",
"descr": "Description",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Apprenez-en plus</0> à propos de la création de vos propres listes de blocage dhôtes.",
@@ -488,5 +510,19 @@
"list_updated": "{{count}} liste mise à jour",
"list_updated_plural": "{{count}} listes mises à jour",
"dnssec_enable": "Activer DNSSEC",
"dnssec_enable_desc": "Définir lindicateur DNSSEC dans les requêtes DNS sortantes et vérifier le résultat (résolveur compatible DNSSEC requis)"
"dnssec_enable_desc": "Définir lindicateur DNSSEC dans les requêtes DNS sortantes et vérifier le résultat (résolveur compatible DNSSEC requis)",
"validated_with_dnssec": "Validé avec DNSSEC",
"show_all_responses": "Toutes les réponses",
"show_blocked_responses": "Bloqué",
"show_whitelisted_responses": "Ajouté à la liste blanche",
"show_processed_responses": "Traité",
"blocked_safebrowsing": "Navigation sécurisée bloquée",
"blocked_adult_websites": "Sites à contenu adulte bloqués",
"blocked_threats": "Menaces bloquées",
"allowed": "Autorisé",
"filtered": "Filtré",
"rewritten": "Réécrit",
"safe_search": "Recherche sécurisée",
"blocklist": "Liste de blocage",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "VI možete odrediti DNS upstream-ove <0>za određene domene</0>",
"upstream_parallel": "Koristi paralelne upite kako bi ubrzali rješavanje istovremenim ispitavanjem svih upstream poslužitelja",
"parallel_requests": "Paralelni zahtjevi",
"load_balancing": "Load-balancing",
"load_balancing_desc": "Šaljite upite po jednom poslužitelju u isto vrijeme. AdGuard Home će koristiti ponderirani slučajni algoritam za odabir poslužitelja, tako da će se najbrži poslužitelj češće koristiti.",
"bootstrap_dns": "Bootstrap DNS poslužitelji",
"bootstrap_dns_desc": "Bootstrap DNS poslužitelji koriste se za rezolvanje IP adresa DoH/DoT rezolvera koje navedete kao upstreams.",
"check_dhcp_servers": "Provjera DHCP poslužitelja",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Odaberite DHCP sučelje",
"dhcp_hardware_address": "Adresa hardvera",
"dhcp_ip_addresses": "IP adrese",
"ip": "IP",
"dhcp_table_hostname": "Naziv računala",
"dhcp_table_expires": "Istječe",
"dhcp_warning": "Ako svejedno želite omogućiti DHCP poslužitelj, provjerite da nema drugog aktivnog DHCP poslužitelja na vašoj mreži. Inače može pokvariti Internet za ostale povezane uređaje!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "Nisu pronađeni statični DHCP leases",
"dhcp_add_static_lease": "Dodaj static lease",
"dhcp_reset": "Jeste li sigurni da želite poništiti DHCP postavke?",
"country": "Država",
"city": "Grad",
"delete_confirm": "Jeste li sigurni da želite ukloniti \"{{key}}\"?",
"form_enter_hostname": "Unesite naziv računala",
"error_details": "Detalji o pogrešci",
"response_details": "Detalji odgovora",
"request_details": "Detalji zahtjeva",
"client_details": "Detalji o klijentu",
"details": "Detalji",
"back": "Natrag",
"dashboard": "Upravljačka ploča",
"settings": "Postavke",
"filters": "Filtri",
"filter": "Filtar",
"query_log": "Zapisnik upita",
"compact": "Kompaktno",
"nothing_found": "Nema rezultata",
"faq": "ČPP",
"version": "Verzija",
"address": "adresa",
"address": "Adresa",
"protocol": "Protokol",
"on": "UKLJUČENO",
"off": "ISKLJUČENO",
"copyright": "Autorsko pravo",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Broj pravila",
"last_time_updated_table_header": "Zadnje ažurirano",
"actions_table_header": "Radnje",
"request_table_header": "Zahtjev",
"edit_table_action": "Uredi",
"delete_table_action": "Ukloni",
"elapsed": "Proteklo",
"filters_and_hosts_hint": "AdGuard Home razumije osnovna pravila blokiranja oglasa i sintaksu hosts datoteka.",
"no_blocklist_added": "Nema dodanih popisa blokiranih",
"no_whitelist_added": "Nema dodanih popisa omogućenih",
@@ -170,12 +185,15 @@
"updated_upstream_dns_toast": "Ažurirani su upstream DNS poslužitelji",
"dns_test_ok_toast": "Odabrani DNS poslužitelji su trenutno aktivni",
"dns_test_not_ok_toast": "\"{{key}}\" poslužitelja: ne može se upotrijebiti, provjerite jeste li to ispravno napisali",
"unblock_btn": "Odblokiraj",
"block_btn": "Blokiraj",
"unblock": "Odblokiraj",
"block": "Blokiraj",
"time_table_header": "Vrijeme",
"date": "Datum",
"domain_name_table_header": "Naziv domene",
"domain_or_client": "Domena ili klijent",
"type_table_header": "Vrsta",
"response_table_header": "Odgovor",
"response_code": "Responzivni kod",
"client_table_header": "Klijent",
"empty_response_status": "Prazno",
"show_all_filter_type": "Prikaži sve",
@@ -194,6 +212,7 @@
"query_log_filtered": "Filtrirao {{filter}}",
"query_log_confirm_clear": "Jeste li sigurni da želite ukloniti zapise upita?",
"query_log_cleared": "Zapisnik upita je uspješno uklonjen",
"query_log_updated": "Zapisnik upita je uspješno ažuriran",
"query_log_clear": "Očisti zapisnik upita",
"query_log_retention": "Spremanje zapisnika upita",
"query_log_enable": "Omogući zapise",
@@ -211,6 +230,9 @@
"custom_ip": "Prilagođen IP",
"blocking_ipv4": "Blokiranje IPv4",
"blocking_ipv6": "Blokiranje IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "Obični DNS",
"form_enter_rate_limit": "Unesite ograničenje",
"rate_limit": "Ograničenje",
"edns_enable": "Omogući EDNS Client Subnet",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Nuliran IP: Odgovor s nuliranom IP adresom (0.0.0.0 za A; :: za AAAA)",
"blocking_mode_custom_ip": "Prilagođeni IP: Odgovor s ručno postavljenom IP adresom",
"upstream_dns_client_desc": "Ako ovo polje ostane prazno, AdGuard Home će upotrijebiti poslužitelje postavljene u <0>DNS postavkama</0>.",
"tracker_source": "Izvor pratitelja",
"source_label": "Izvor",
"found_in_known_domain_db": "Pronađeno u bazi poznatih domena.",
"category_label": "Kategorija",
"rule_label": "Pravilo",
"list_label": "Popis",
"unknown_filter": "Nepoznati filtar {{filterId}}",
"known_tracker": "Poznati pratitelj",
"install_welcome_title": "Dobrodošli u AdGuard Home!",
"install_welcome_desc": "AdGuard Home je DNS poslužitelj za blokiranje oglasa i pratitelja na cijeloj mreži. Njegova je svrha omogućiti vam upravljanje cijelom mrežom i svim svojim uređajima, a da to ne zahtijeva korištenje programa na strani klijenta.",
"install_settings_title": "Administratorsko web sučelje",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "Otvorite postavke za router. Obično mu možete pristupiti iz preglednika putem URL-a (kao što je http://192.168.0.1/ ili http://192.168.1.1/). Od vas će se možda tražiti da unesete lozinku. Ako je se ne sjećate, lozinku možete često poništiti pritiskom na dumge na samom routeru. Neki routeri trebaju određenu aplikaciju, koja bi u tom slučaju trebala biti već instalirana na vašem računalu/telefonu.",
"install_devices_router_list_2": "Pronađite DHCP/DNS postavke. Potražite DNS slova pored polja koje dopušta dva ili tri skupa brojeva, svaki razdvojen u četiri skupine od jedne do tri znamenke.",
"install_devices_router_list_3": "Unesite adresu AdGuard Home poslužitelja ovdje.",
"install_devices_router_list_4": "Ne možete postaviti prilagođeni DNS poslužitelj na nekim vrstama routera. U ovom slučaju, može vam pomoći ako postavite AdGuard Home kao DHCP poslužitelj. U suprotnom, trebali biste potražiti priručnik o tome kako prilagoditi DNS poslužitelje za vaš određeni model routera.",
"install_devices_router_list_4": "Ne možete postaviti prilagođeni DNS poslužitelj na nekim vrstama routera. U ovom slučaju, može vam pomoći ako postavite AdGuard Home kao <0>DHCP poslužitelj</0>. U suprotnom, trebali biste potražiti priručnik o tome kako prilagoditi DNS poslužitelje za vaš određeni model routera.",
"install_devices_windows_list_1": "Otvorite Upravljačku ploču putem Start izbornika ili Windows pretrage.",
"install_devices_windows_list_2": "Idite na kategoriju Mreža i Internet i odaberite Centar za mreže i zajedničko korištenje.",
"install_devices_windows_list_3": "Na lijevoj strani zaslona pronađite Promjeni postavke adaptera i pritisnite na to.",
@@ -346,6 +370,7 @@
"form_enter_id": "Unesi identifikator",
"form_add_id": "Dodaj identifikator",
"form_client_name": "Unesite naziv klijenta",
"name": "Naziv",
"client_global_settings": "Koristi globalne postavke",
"client_deleted": "Klijent \"{{key}}\" je uspješno uklonjen",
"client_added": "Klijent \"{{key}}\" je uspješno dodan",
@@ -445,6 +470,7 @@
"location": "Lokacija",
"orgname": "Naziv organizacije",
"netname": "Naziv mreže",
"network": "Mreža",
"descr": "Opis",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Saznajte više</0> o stvaranju vlastitog popisa poslužitelja.",
@@ -456,7 +482,7 @@
"disable_ipv6": "Onemogući IPv6",
"disable_ipv6_desc": "Ukoliko je ova značajka omogućena, svi DNS upiti za IPv6 adrese (AAAA tip) će biti odbačeni.",
"fastest_addr": "Najbrža IP adresa",
"fastest_addr_desc": "Ispitajte sve DNS poslužitelje i vratite najbržu IP adresu među svim odgovorima",
"fastest_addr_desc": "Ispitajte sve DNS poslužitelje i vratite najbržu IP adresu među svim odgovorima. Ovo će usporiti DNS upite jer moramo čekati odgovore sa svih DNS poslužitelja, ali će poboljšati cjelokupnu povezanost.",
"autofix_warning_text": "Ako pritisnete \"Popravi\", AdGuard Home će postaviti vaš sustav da koristi AdGuardHome DNS poslužitelj.",
"autofix_warning_list": "Izvodi sljedeće radnje: <0>Deaktiviraj DNSStubListener sustav</0> <0>Postavi adresu DNS poslužitelja na 127.0.0.1</0> <0>Zamijeni simbolički cilj veze iz /etc/resolv.conf u /run/systemd/resolve/resolv.conf</0> <0>Zaustavi DNSStubListener (ponovno pokreni systemd-resolved uslugu)</0>",
"autofix_warning_result": "Kao rezultat toga, sve DNS zahtjeve iz vašeg sustava će AdGuard Home obraditi prema zadanim postavkama.",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} popis ažuriran",
"list_updated_plural": "{{count}} popisa ažurirana",
"dnssec_enable": "Omogući DNSSEC",
"dnssec_enable_desc": "Omogućite DNSSEC u izlaznim DNS upitima i provjerite rezultat (potreban je resolver s omogućenim DNSSEC-om)"
"dnssec_enable_desc": "Omogućite DNSSEC u izlaznim DNS upitima i provjerite rezultat (potreban je resolver s omogućenim DNSSEC-om)",
"validated_with_dnssec": "Potvrđeno s DNSSEC-om",
"show_all_responses": "Svi odgovori",
"show_blocked_responses": "Blokirano",
"show_whitelisted_responses": "Na popisu dopuštenih",
"show_processed_responses": "Obrađeno",
"blocked_safebrowsing": "Blokirano s Sigurnom pretragom",
"blocked_adult_websites": "Blokirane web stranice za odrasle",
"blocked_threats": "Blokirane prijetnje",
"allowed": "Dopušteno",
"filtered": "Filtrirano",
"rewritten": "Prepisano",
"safe_search": "Sigurno pretraživanje",
"blocklist": "Popis neželjenih",
"milliseconds_abbreviation": "ms"
}

View File

@@ -37,6 +37,7 @@
"dhcp_interface_select": "Pilih antarmuka DHCP",
"dhcp_hardware_address": "Alamat perangkat keras",
"dhcp_ip_addresses": "Alamat IP",
"ip": "IP",
"dhcp_table_hostname": "Nama host",
"dhcp_table_expires": "Kadaluwarsa",
"dhcp_warning": "Jika anda ingin mengaktifkan server DHCP bawaan, pastikan tidak ada server DHCP lain yang aktif. Jika tidak, akan memutus koneksi internet pada perangkat yang telah terhubung!",
@@ -49,17 +50,23 @@
"dhcp_static_leases_not_found": "DHCP static lease tidak ditemukan",
"dhcp_add_static_lease": "Tambah static lease",
"dhcp_reset": "Apakah anda yakin ingin mengatur ulang konfigurasi DHCP anda?",
"country": "Negara",
"delete_confirm": "Apakah anda yakin ingin menghapus \"{{key}}\"?",
"form_enter_hostname": "Masukkan hostname",
"error_details": "Detail kesalahan",
"request_details": "Detai permintaan",
"client_details": "Detail klien",
"details": "Detail",
"back": "Kembali",
"dashboard": "Beranda",
"settings": "Pengaturan",
"filters": "Penyaring",
"filter": "Filter",
"query_log": "Catatan Kueri",
"faq": "Tanya Jawab",
"version": "versi",
"address": "alamat",
"address": "Alamat",
"protocol": "Protokol",
"on": "HIDUP",
"off": "MATI",
"copyright": "Hak cipta",
@@ -107,6 +114,7 @@
"general_settings": "Pengaturan umum",
"dns_settings": "Pengaturan DNS",
"dns_blocklists": "Daftar blokir DNS",
"custom_filtering_rules": "Aturan penyaringan khusus",
"encryption_settings": "Pengaturan enkripsi",
"dhcp_settings": "Pengaturan DHCP",
"upstream_dns": "Server DNS hulu",
@@ -126,8 +134,10 @@
"rules_count_table_header": "Jumlah Aturan",
"last_time_updated_table_header": "Terakhir diperbaharui",
"actions_table_header": "Aksi",
"request_table_header": "Permintaan",
"edit_table_action": "Ubah",
"delete_table_action": "Hapus",
"elapsed": "Berlalu",
"filters_and_hosts_hint": "AdGuard Home memahami aturan dasar adblock dan sintak file hosts.",
"cancel_btn": "Batal",
"enter_name_hint": "Masukkan nama",
@@ -145,17 +155,19 @@
"example_comment_hash": "Juga sebuah komentar",
"example_regex_meaning": "blokir akses ke domain yang cocok dengan <0>ekspresi reguler yang ditentukan</0>",
"example_upstream_regular": "DNS reguler (melalui UDP)",
"example_upstream_dot": "terenkripsi <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a>",
"example_upstream_doh": "terenkripsi <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "anda bisa menggunakan <a href='https://dnscrypt.info/stamps/' target='_blank'>Stempel DNS</a> untuk <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> atau pengarah <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_dot": "terenkripsi <0>DNS-over-TLS</0>",
"example_upstream_doh": "terenkripsi <0>DNS-over-HTTPS</0>",
"example_upstream_sdns": "anda bisa menggunakan <0>Stempel DNS</0> untuk <1>DNSCrypt</1> atau pengarah <2>DNS-over-HTTPS</2>",
"example_upstream_tcp": "DNS reguler (melalui TCP)",
"updated_upstream_dns_toast": "Server DNS hulu terbarui",
"dns_test_ok_toast": "Server DNS yang ditentukan bekerja dengan benar",
"dns_test_not_ok_toast": "Server \"{{key}}\": tidak dapat digunakan, mohon cek bahwa Anda telah menulisnya dengan benar",
"unblock_btn": "Buka Blokir",
"block_btn": "Blokir",
"unblock": "Buka Blokir",
"block": "Blok",
"time_table_header": "Waktu",
"date": "Tanggal",
"domain_name_table_header": "Nama domain",
"domain_or_client": "Domain atau klien",
"type_table_header": "Tipe",
"response_table_header": "Respon",
"client_table_header": "Klien",
@@ -184,8 +196,11 @@
"query_log_strict_search": "Gunakan tanda kutip ganda untuk pencarian ketat",
"query_log_retention_confirm": "Apakah Anda yakin ingin mengubah retensi kueri log? Jika Anda menurunkan nilai interval, beberapa data akan hilang",
"blocking_mode": "Mode blokir",
"default": "Standar",
"blocking_ipv4": "Blokiran IPv4",
"blocking_ipv6": "Blokiran IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"edns_cs_desc": "Apabila dinyalakan, AdGuard Home akan mengirim subnet klien ke server-server DNS.",
"rate_limit_desc": "Jumlah permintaan per detik yang diperbolehkan untuk satu klien (0: tidak terbatas)",
"blocking_mode_custom_ip": "IP kustom: respon dengan alamat IP yang diset secara manual",
@@ -194,6 +209,7 @@
"category_label": "Kategori",
"rule_label": "Aturan",
"unknown_filter": "Penyaringan {{filterId}} tidak dikenal",
"known_tracker": "Pelacak yang dikenal",
"install_welcome_title": "Selamat datang di AdGuard Home!",
"install_welcome_desc": "AdGuard Home adalah sebuah server DNS pemblokiran iklan dan pelacak di jaringan. Tujuannya adalah memungkinkan anda mengkontrol seluruh jaringan dan semua perangkat anda, dan ini tidak membutuhkan aplikasi tambahan di klien",
"install_settings_title": "Antarmuka Halaman Admin",
@@ -222,7 +238,7 @@
"install_devices_router_list_1": "Buka preferensi untuk router Anda. Biasanya, Anda dapat mengaksesnya dari browser Anda melalui URL (seperti http://192.168.0.1/ atau http://192.168.1.1/). Anda mungkin diminta memasukkan kata sandi. Jika Anda tidak mengingatnya, Anda dapat mengatur ulang kata sandi dengan menekan tombol atur ulang (reset) pada router. Beberapa router ada yang memerlukan aplikasi tertentu, dalam hal ini harus sudah diinstal pada komputer / telepon Anda.",
"install_devices_router_list_2": "Temukan pengaturan DHCP / DNS. Cari huruf DNS di sebelah bidang yang memungkinkan dua atau tiga set angka, masing-masing dipecah menjadi empat grup dengan satu hingga tiga digit.",
"install_devices_router_list_3": "Masukkan alamat server AdGuard Home disana",
"install_devices_router_list_4": "Anda tidak dapat menyetel server DNS kustom pada beberapa tipe router. Dalam hal ini mungkin membantu jika Anda mengatur AdGuard Home sebagai server DHCP. Jika tidak, Anda harus mencari petunjuk tentang cara mengkustomisasi server DNS untuk model router khusus Anda.",
"install_devices_router_list_4": "Anda tidak dapat menyetel server DNS kustom pada beberapa tipe router. Dalam hal ini mungkin membantu jika Anda mengatur AdGuard Home sebagai <0>server DHCP</0>. Jika tidak, Anda harus mencari petunjuk tentang cara mengkustomisasi server DNS untuk model router khusus Anda.",
"install_devices_windows_list_1": "Buka Panel Kontrol melalui menu Start atau pencarian Windows.",
"install_devices_windows_list_2": "Masuk ke kategori Jaringan dan Internet (Network and Internet) dan kemudian ke Pusat Jaringan dan Berbagi (Network and Sharing Center).",
"install_devices_windows_list_3": "Di sisi kiri layar temukan Ubah pengaturan adaptor dan klik.",
@@ -309,6 +325,7 @@
"form_enter_ip": "Masukkan IP",
"form_enter_mac": "Masukkan MAC",
"form_client_name": "Masukkan nama klien",
"name": "Nama",
"client_global_settings": "Gunakan pengaturan global",
"client_deleted": "Klien \"{{key}}\" berhasil dihapus",
"client_added": "Klien \"{{key}}\" berhasil ditambahkan",
@@ -406,6 +423,7 @@
"location": "Lokasi",
"orgname": "Nama organisasi",
"netname": "Nama jaringan",
"network": "Jaringan",
"descr": "Deskripsi",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Pelajari lebih lanjut</0> tentang membuat daftar hitam host Anda sendiri.",
@@ -427,5 +445,13 @@
"client_confirm_unblock": "Apa anda yakin ingin meng-unblock klien ini \"{{ip}}\"?",
"client_blocked": "Klien \"{{ip}}\" sukses di blokir",
"client_unblocked": "Klien \"{{ip}}\" sukses di unblock",
"static_ip": "Alamat IP statis"
"static_ip": "Alamat IP statis",
"validated_with_dnssec": "Tervalidasi dengan DNSSEC",
"show_all_responses": "Semua respon",
"show_blocked_responses": "Diblokir",
"show_whitelisted_responses": "Dalam Daftar Putih",
"show_processed_responses": "Terproses",
"safe_search": "Pencarian aman",
"blocklist": "Daftar blokir",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Puoi specificare un server DNS<0>per uno specifico dominio(i)</0>",
"upstream_parallel": "Usa le query parallele per accelerare la risoluzione interrogando simultaneamente tutti i server",
"parallel_requests": "Richieste parallele",
"load_balancing": "Bilanciamento del carico",
"load_balancing_desc": "Interroga un server per volta. AdGuardHome userà l'algoritmo soppesato casualmente per scegliere il server così che quello più veloce sarà usato più spesso.",
"bootstrap_dns": "Server DNS di avvio",
"bootstrap_dns_desc": "Server DNS usati per risolvere gli indirizzi IP dei risolutori DoH/DoT specificati come upstreams.",
"check_dhcp_servers": "Controlla la presenza di server DHCP",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Seleziona l'interfaccia DHCP",
"dhcp_hardware_address": "Indirizzo hardware",
"dhcp_ip_addresses": "Indirizzi IP",
"ip": "IP",
"dhcp_table_hostname": "Nome host",
"dhcp_table_expires": "Scaduto",
"dhcp_warning": "Se si desidera abilitare il server DHCP integrato, assicurarsi che non vi siano altri server DHCP attivi. Altrimenti, possono sussistere problemi di rete per i dispositivi collegati!",
@@ -49,17 +52,25 @@
"dhcp_static_leases_not_found": "Non è stato trovato nessun leases statico DHCP",
"dhcp_add_static_lease": "Aggiungi lease statico",
"dhcp_reset": "Sei sicuro di voler ripristinare la configurazione DHCP?",
"country": "Regione",
"city": "Città",
"delete_confirm": "Sei sicuro di voler cancellare \"{{key}}\"?",
"form_enter_hostname": "Inserisci hostname",
"error_details": "Dettagli errore",
"response_details": "Dettagli di Risposta",
"request_details": "Dettagli della richiesta",
"client_details": "Dettagli client",
"details": "Dettagli",
"back": "Indietro",
"dashboard": "Cruscotto",
"settings": "Impostazioni",
"filters": "Filtri",
"filter": "Filtro",
"query_log": "Query Log",
"faq": "FAQ",
"version": "versione",
"address": "indirizzo IP",
"address": "Indirizzo",
"protocol": "Protocollo",
"on": "ATTIVO",
"off": "DISATTIVATO",
"copyright": "Copyright",
@@ -132,8 +143,10 @@
"rules_count_table_header": "Numero regole",
"last_time_updated_table_header": "Ultimo aggiornamento",
"actions_table_header": "Azioni",
"request_table_header": "Richiesta",
"edit_table_action": "Modifica",
"delete_table_action": "Elimina",
"elapsed": "Trascorso",
"filters_and_hosts_hint": "AdGuard Home è in grado di comprendere la sintassi delle regole di adblock o quelle dei file hosts",
"no_blocklist_added": "Non è stata aggiunta alcuna lista di blocco",
"no_whitelist_added": "Non è stata aggiunta alcuna lista dei consentiti",
@@ -162,18 +175,20 @@
"example_comment_hash": "# Un altro commento",
"example_regex_meaning": "blocca l'accesso ai domini che corrispondono alla specifica espressione regolare",
"example_upstream_regular": "DNS regolari (via UDP)",
"example_upstream_dot": "<a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a> criptato",
"example_upstream_doh": "<a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> criptato",
"example_upstream_sdns": "puoi usare <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> per <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> oppure dei resolver con <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_dot": "<0>DNS_over_TLS</0> crittografato",
"example_upstream_doh": "<0>DNS-over-HTTPS</0> crittografato",
"example_upstream_sdns": "puoi usare <0>DNS Stamps</0> per <1>DNSCrypt</1> oppure dei resolver con <2>DNS-over-HTTPS</2>",
"example_upstream_tcp": "DNS regolari (via TCP)",
"all_lists_up_to_date_toast": "Tutte le liste sono aggiornate",
"updated_upstream_dns_toast": "Server DNS upstream aggiornati",
"dns_test_ok_toast": "I server DNS specificati funzionano correttamente",
"dns_test_not_ok_toast": "Server \"{{key}}\": non può essere usato, assicurati di averlo digitato correttamente",
"unblock_btn": "Sblocca",
"block_btn": "Blocca",
"unblock": "Sblocca",
"block": "Blocca",
"time_table_header": "Ora",
"date": "Data",
"domain_name_table_header": "Nome dominio",
"domain_or_client": "Dominio o client",
"type_table_header": "Tipo",
"response_table_header": "Risposta",
"client_table_header": "Client",
@@ -211,6 +226,9 @@
"custom_ip": "IP personalizzato",
"blocking_ipv4": "Blocca IPv4",
"blocking_ipv6": "Blocca IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "DNS semplice",
"form_enter_rate_limit": "Imposta limite delle richieste",
"rate_limit": "Limite delle richieste",
"edns_enable": "Abilita client di sottorete EDNS",
@@ -229,6 +247,7 @@
"rule_label": "Regola",
"list_label": "Lista",
"unknown_filter": "Filtro sconosciuto {{filterId}}",
"known_tracker": "Tracker conosciuto",
"install_welcome_title": "Benvenuto nella Home di AdGuard!",
"install_welcome_desc": "AdGuard Home è un server DNS che blocca annunci e tracker in tutta la rete. Il suo scopo è quello di consentire di controllare l'intera rete e tutti i dispositivi, e non richiede l'utilizzo di un programma sul lato client.",
"install_settings_title": "Interfaccia Web dell'Admin",
@@ -257,7 +276,7 @@
"install_devices_router_list_1": "Apri le preferenze per il tuo router. Di solito, puoi accedervi dal tuo browser tramite un URL (come http://192.168.0.1/ o http://192.168.1.1/). Potrebbe essere richiesto di inserire la password. Se non lo ricordi, puoi spesso reimpostare la password premendo un pulsante sul router stesso. Alcuni router richiedono un'applicazione specifica, che in quel caso dovrebbe essere già installata sul tuo computer / telefono.",
"install_devices_router_list_2": "Trova le impostazioni DHCP / DNS. Cerca le lettere DNS accanto a un campo che consente due o tre serie di numeri, ciascuno suddiviso in quattro gruppi di 1-3 cifre.",
"install_devices_router_list_3": "Inserisci qui gli indirizzi del tuo server AdGuard Home.",
"install_devices_router_list_4": "Non puoi impostare un server DNS personalizzato o alcun tipo di router. In questi casi potrebbe essere di aiuto impostare la pagina principale di AdGuard come server DHCP. In alternativa, dovresti cercare sul manuale il modo per personalizzare i server DNS per il tuo particolare modello di router.",
"install_devices_router_list_4": "Non puoi impostare un server DNS personalizzato o alcun tipo di router. In questi casi potrebbe essere di aiuto impostare la pagina principale di AdGuard come <0>server DHCP</0>. In alternativa, dovresti cercare sul manuale il modo per personalizzare i server DNS per il tuo particolare modello di router.",
"install_devices_windows_list_1": "Aprire il Pannello di controllo tramite il menu Start o la ricerca di Windows.",
"install_devices_windows_list_2": "Vai a Rete e categoria Internet e poi a Centro connessioni di rete e condivisione.",
"install_devices_windows_list_3": "Sul lato sinistro dello schermo, trova le impostazioni della scheda Cambia e fai clic su di esso.",
@@ -346,6 +365,7 @@
"form_enter_id": "Inserisci identificatore",
"form_add_id": "Aggiungi identificatore",
"form_client_name": "Inserisci nome client",
"name": "Nome",
"client_global_settings": "Usa le impostazioni globali",
"client_deleted": "Client \"{{key}}\" eliminato correttamente",
"client_added": "Client \"{{key}}\" aggiunto correttamente",
@@ -445,6 +465,7 @@
"location": "Locazione",
"orgname": "Nome dell'organizzazione",
"netname": "Nome Network",
"network": "Rete",
"descr": "Descrizione",
"whois": "Chi è",
"filtering_rules_learn_more": "<0>Leggi altro</0> su come creare i tuoi host blacklist.",
@@ -489,5 +510,19 @@
"list_updated": "{{count}} lista aggiornata",
"list_updated_plural": "{{count}} liste aggiornate",
"dnssec_enable": "Abilita DNSSEC",
"dnssec_enable_desc": "Imposta la spunta DNSSEC nelle interrogazioni DNS in uscita e verifica il risultato (è richiesta l'attivazione del risolutore DNSSEC)"
"dnssec_enable_desc": "Imposta la spunta DNSSEC nelle interrogazioni DNS in uscita e verifica il risultato (è richiesta l'attivazione del risolutore DNSSEC)",
"validated_with_dnssec": "Verificato con DNSSEC",
"show_all_responses": "Tutti i responsi",
"show_blocked_responses": "Bloccato",
"show_whitelisted_responses": "Nella whitelist",
"show_processed_responses": "Processato",
"blocked_safebrowsing": "Blocco Navigazione sicura",
"blocked_adult_websites": "Siti per adulti bloccati",
"blocked_threats": "Minacce bloccate",
"allowed": "Consentito",
"filtered": "Filtrato",
"rewritten": "Riscritto",
"safe_search": "Ricerca sicura",
"blocklist": "Lista di blocco",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "<0>特定のドメイン</0>に対してDNSアップストリームを指定できます",
"upstream_parallel": "並列リクエストを使用する(すべてのアップストリームサーバーを同時に照会することで解決スピードが向上します)",
"parallel_requests": "並列リクエスト",
"load_balancing": "ロードバランシング",
"load_balancing_desc": "一度に1つのサーバを照会します。 AdGuard Homeは、重み付きランダムアルゴリズムを使用してサーバを選択するため、最速のサーバがより頻繁に使用されます。",
"bootstrap_dns": "ブートストラップDNSサーバ",
"bootstrap_dns_desc": "ブートストラップDNSサーバは、上流として指定したDoHDoTリゾルバのIPアドレスを解決するために使用されます。",
"check_dhcp_servers": "DHCPサーバをチェックする",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "DHCPインタフェースの選択",
"dhcp_hardware_address": "MACアドレス",
"dhcp_ip_addresses": "IPアドレス",
"ip": "IP",
"dhcp_table_hostname": "ホスト名",
"dhcp_table_expires": "有効期限",
"dhcp_warning": "内蔵しているDHCPサーバを有効にしたい場合は、稼働中のDHCPサーバがないことを確認してください。そうでなければ、接続されたデバイスのためにインターネットを壊すかもしれません",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "DHCP静的割り当てはありません",
"dhcp_add_static_lease": "静的割り当てを追加する",
"dhcp_reset": "DHCP設定をリセットして良いですか",
"country": "国",
"city": "街",
"delete_confirm": "\"{{key}}\" を削除してもよろしいですか?",
"form_enter_hostname": "ホスト名を入力してください",
"error_details": "エラー詳細",
"response_details": "応答の詳細",
"request_details": "要求の詳細",
"client_details": "クライアントの詳細",
"details": "詳細",
"back": "戻る",
"dashboard": "ダッシュボード",
"settings": "設定",
"filters": "フィルタ",
"filter": "フィルタ",
"query_log": "クエリ・ログ",
"compact": "コンパクト",
"nothing_found": "何も見つかりません",
"faq": "よくある質問",
"version": "バージョン",
"address": "アドレス",
"protocol": "プロトコル",
"on": "オン",
"off": "オフ",
"copyright": "著作権",
@@ -132,8 +145,10 @@
"rules_count_table_header": "ルール数",
"last_time_updated_table_header": "最終更新時刻",
"actions_table_header": "操作",
"request_table_header": "リクエスト",
"edit_table_action": "編集する",
"delete_table_action": "削除する",
"elapsed": "経過",
"filters_and_hosts_hint": "AdGuard Homeは、基本的な広告ブロックルールとhostsファイルの構文を理解します。",
"no_blocklist_added": "ブロックリストには何も追加されていません",
"no_whitelist_added": "許可リストには何も追加されていません",
@@ -162,20 +177,23 @@
"example_comment_hash": "# ここもコメントです",
"example_regex_meaning": "指定の正規表現に一致するドメインへのアクセスをブロックします",
"example_upstream_regular": "通常のDNSUDPでの問い合わせ",
"example_upstream_dot": "暗号化されている <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a>",
"example_upstream_doh": "暗号化されている <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "<a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> または <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> リゾルバのために <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> を使えます",
"example_upstream_dot": "暗号化されている <0>DNS-over-TLS</0>",
"example_upstream_doh": "暗号化されている <0>DNS-over-HTTPS</0>",
"example_upstream_sdns": "<1>DNSCrypt</1> または <2>DNS-over-HTTPS</2> リゾルバのために <0>DNS Stamps</0> を使えます",
"example_upstream_tcp": "通常のDNSTCPでの問い合わせ",
"all_lists_up_to_date_toast": "すべてのリストは既に最新です",
"updated_upstream_dns_toast": "上流DNSサーバを更新しました",
"dns_test_ok_toast": "指定されたDNSサーバは正しく動作しています",
"dns_test_not_ok_toast": "サーバ \"{{key}}\": 使用できませんでした。正しく入力されているかどうかを確認してください",
"unblock_btn": "ブロック解除",
"block_btn": "ブロックする",
"unblock": "ブロック解除",
"block": "ブロック",
"time_table_header": "時刻",
"date": "購入日時",
"domain_name_table_header": "ドメイン名",
"domain_or_client": "ドメインまたはクライアント",
"type_table_header": "種類",
"response_table_header": "応答",
"response_code": "応答コード",
"client_table_header": "クライアント",
"empty_response_status": "未定義",
"show_all_filter_type": "すべて表示",
@@ -194,6 +212,7 @@
"query_log_filtered": "{{filter}}によるフィルタ",
"query_log_confirm_clear": "クエリ・ログ全体を消去してもよろしいですか?",
"query_log_cleared": "クエリ・ログの消去に成功しました",
"query_log_updated": "クエリ・ログの更新が成功しました",
"query_log_clear": "クエリ・ログを消去する",
"query_log_retention": "クエリ・ログの保持",
"query_log_enable": "ログを有効にする",
@@ -211,6 +230,9 @@
"custom_ip": "カスタムIP",
"blocking_ipv4": "ブロック中のIPv4",
"blocking_ipv6": "ブロック中のIPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "通常のDNS",
"form_enter_rate_limit": "頻度制限を入力してください",
"rate_limit": "頻度制限",
"edns_enable": "EDNSクライアント・サブネットを有効にする",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Null IPゼロのIPアドレスで応答しますAの場合は0.0.0.0; AAAAの場合は::",
"blocking_mode_custom_ip": "カスタムIP手動で設定されたIPアドレスで応答します",
"upstream_dns_client_desc": "このフィールドを未入力のままにすると、AdGuard Homeは<0>DNS設定</0>で構成されたサーバを使用します。",
"tracker_source": "追跡元",
"source_label": "ソース",
"found_in_known_domain_db": "既知のドメインデータベースに見つかりました。",
"category_label": "カテゴリ",
"rule_label": "ルール",
"list_label": "リスト",
"unknown_filter": "不明なフィルタ {{filterId}}",
"known_tracker": "既知のトラッカー",
"install_welcome_title": "ようこそ、AdGuard Home へ!",
"install_welcome_desc": "AdGuard Homeは、ネットワーク全体で広告と追跡をブロックするDNSサーバです。その目的は、ネットワークとデバイスのすべてをあなたが制御できるようにすることであり、クライアント側のプログラムを使用する必要はありません。",
"install_settings_title": "管理用ウェブインターフェイス",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "ルータの設定を開きます。通常は、URLhttp://192.168.0.1/ または http://192.168.1.1/ など)を介してブラウザからアクセスできます。パスワードの入力を求められることがあります。パスワードを覚えていない場合は、ルータにあるボタンを押してパスワードをリセットできます。一部のルータは特定のアプリケーションを必要とします。その場合、アプリケーションはあなたのコンピュータ/電話に既にインストールされているはずです。",
"install_devices_router_list_2": "DHCPDNSの設定を見つけます。DNSの文字のある入力欄を探します。それは、1〜3桁の数字で4つのグループに分けられた入力欄で、セットを許可されている欄です。",
"install_devices_router_list_3": "そこにAdGuard Homeサーバのアドレスを入力します。",
"install_devices_router_list_4": "一部のタイプのルータではカスタムDNSサーバを設定できません。この場合、AdGuard HomeをDHCPサーバとして設定することがおすすめです。それ以外の場合は、特定のルータモデルに合わせてDNSサーバをカスタマイズする方法に関するマニュアルを検索する必要があります。",
"install_devices_router_list_4": "一部のタイプのルータではカスタムDNSサーバを設定できません。この場合、AdGuard Homeを<0>DHCPサーバ</0>として設定するとお役に立ちます。それ以外の場合は、特定のルータモデルに合わせてDNSサーバをカスタマイズする方法に関するマニュアルを検索する必要があります。",
"install_devices_windows_list_1": "「スタート」メニューまたはWindowsの検索から「設定」を開きます。",
"install_devices_windows_list_2": "「ネットワークとインターネット」カテゴリに移動し、さらに「ネットワークと共有センター」へ移動します。",
"install_devices_windows_list_3": "画面の左側にある「アダプターの設定の変更」を見つけてクリックします。",
@@ -346,6 +370,7 @@
"form_enter_id": "識別子を入力してください",
"form_add_id": "識別子を追加する",
"form_client_name": "クライアント名を入力してください",
"name": "名前",
"client_global_settings": "グローバル設定を使用する",
"client_deleted": "クライアント \"{{key}}\" の削除に成功しました",
"client_added": "クライアント \"{{key}}\" の追加に成功しました",
@@ -361,6 +386,8 @@
"access_allowed_desc": "CIDRまたはIPアドレスのリスト。設定されると、AdGuard HomeはこれらのIPアドレスからのリクエストのみを許可します。",
"access_disallowed_title": "拒否するクライアント",
"access_disallowed_desc": "CIDRまたはIPアドレスのリスト。設定されると、AdGuard HomeはこれらのIPアドレスからのリクエストを破棄します。",
"access_blocked_title": "拒否するドメイン",
"access_blocked_desc": "これをフィルタと混同しないでください。AdGuard Homeは、これらのドメインを含むDNSクエリを破棄します。",
"access_settings_saved": "アクセス設定の保存に成功しました",
"updates_checked": "アップデートの確認に成功しました",
"updates_version_equal": "AdGuard Homeは既に最新です",
@@ -443,6 +470,7 @@
"location": "ロケーション",
"orgname": "組織名",
"netname": "ネットワーク名",
"network": "ネットワーク",
"descr": "説明",
"whois": "Whois",
"filtering_rules_learn_more": "独自ホストリストの作成についての<0>詳細はこちら</0>。",
@@ -486,5 +514,20 @@
"confirm_static_ip": "AdGuard Homeは、{{ip}}を静的IPアドレスとして設定します。よろしいですか",
"list_updated": "{{count}}個のリストが更新されました",
"list_updated_plural": "{{count}}個のリストが更新されました",
"dnssec_enable": "DNSSECを有効にする"
}
"dnssec_enable": "DNSSECを有効にする",
"dnssec_enable_desc": "DNSクエリの応答にDNSSECフラグを設定し、結果を確認しますDNSSEC対応のリゾルバが必要です",
"validated_with_dnssec": "DNSSECにて検証済",
"show_all_responses": "すべての応答",
"show_blocked_responses": "ブロック済",
"show_whitelisted_responses": "ホワイトリストにあり",
"show_processed_responses": "処理済",
"blocked_safebrowsing": "ブロックされたセーフブラウジング",
"blocked_adult_websites": "ブロックされたアダルトウェブサイト",
"blocked_threats": "ブロックされた脅威",
"allowed": "許可",
"filtered": "フィルタで処理",
"rewritten": "書換",
"safe_search": "セーフサーチ",
"blocklist": "ブロックリスト",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "<0>특정 도메인에 대한</0> DNS 업스트림을 지정할 수 있습니다.",
"upstream_parallel": "쿼리 처리 속도를 높이려면 모든 업스트림 서버에서 동시에 병렬 쿼리를 사용해주세요.",
"parallel_requests": "병렬 처리 요청",
"load_balancing": "로드 밸런싱",
"load_balancing_desc": "한 번에 하나의 서버씩 질의합니다. AdGuard Home은 가중 랜덤 알고리즘를 사용해서 가장 빠른 서버가 자주 사용되도록 서버를 선택합니다.",
"bootstrap_dns": "부트스트랩 DNS 서버",
"bootstrap_dns_desc": "부트스트랩 DNS 서버는 업스트림으로 지정한 DoH/DoT 서버의 IP 주소를 확인하는 데 사용합니다.",
"check_dhcp_servers": "DHCP 서버 체크",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "DHCP 인터페이스 선택",
"dhcp_hardware_address": "하드웨어 주소",
"dhcp_ip_addresses": "IP 주소",
"ip": "IP",
"dhcp_table_hostname": "호스트 이름",
"dhcp_table_expires": "만료",
"dhcp_warning": "DHCP 서버를 사용하려면 네트워크에 다른 활성 DHCP 서버가 없는지 확인해주세요. 다른 활성 DHCP 서버가 있다면, 연결된 장치의 인터넷을 끊을 수 있습니다.",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "DHCP 고정 임대를 찾을 수 없음",
"dhcp_add_static_lease": "고정 임대 추가",
"dhcp_reset": "정말로 DHCP 설정을 초기화할까요?",
"country": "지역",
"city": "도시",
"delete_confirm": "\"{{key}}\"을 삭제하시겠습니까?",
"form_enter_hostname": "호스트 이름을 입력해주세요",
"error_details": "오류 상세 정보",
"response_details": "응답 정보",
"request_details": "요청 세부 사항",
"client_details": "클라이언트 정보",
"details": "정보",
"back": "뒤로",
"dashboard": "대시보드",
"settings": "설정",
"filters": "필터",
"filter": "필터",
"query_log": "쿼리 로그",
"compact": "콤팩트",
"nothing_found": "아무것도 찾을 수 없습니다",
"faq": "자주 묻는 질문",
"version": "버전",
"address": "주소",
"protocol": "프로토콜",
"on": "ON",
"off": "OFF",
"copyright": "Copyright",
@@ -132,8 +145,10 @@
"rules_count_table_header": "규칙 개수",
"last_time_updated_table_header": "마지막 업데이트",
"actions_table_header": "가능한 동작",
"request_table_header": "요청",
"edit_table_action": "편집",
"delete_table_action": "삭제",
"elapsed": "소요",
"filters_and_hosts_hint": "AdGuard Home은 기본적인 광고 차단 규칙과 호스트 파일 문법을 읽을 수 있습니다",
"no_blocklist_added": "차단 목록이 추가되지 않음",
"no_whitelist_added": "허용 목록이 추가되지 않음",
@@ -170,12 +185,15 @@
"updated_upstream_dns_toast": "업스트림 DNS 서버를 업데이트하였습니다",
"dns_test_ok_toast": "특정 DNS 서버들은 정상적으로 동작 중입니다",
"dns_test_not_ok_toast": "서버 \"{{key}}\": 사용할 수 없습니다, 제대로 작성했는지 확인하세요.",
"unblock_btn": "차단 해제",
"block_btn": "차단",
"unblock": "차단 해제",
"block": "차단",
"time_table_header": "시간",
"date": "날짜",
"domain_name_table_header": "도메인명",
"domain_or_client": "도메인 또는 클라이언트",
"type_table_header": "유형",
"response_table_header": "응답",
"response_code": "응답 코드",
"client_table_header": "클라이언트",
"empty_response_status": "비어있음",
"show_all_filter_type": "모두 표시",
@@ -194,6 +212,7 @@
"query_log_filtered": "필터: {{filter}}",
"query_log_confirm_clear": "정말로 모든 쿼리 로그를 비우시겠습니까?",
"query_log_cleared": "쿼리 로그를 성공적으로 초기화했습니다",
"query_log_updated": "질의 로그가 성공적으로 업데이트되었습니다",
"query_log_clear": "쿼리 로그 비우기",
"query_log_retention": "쿼리 로그 저장 기간",
"query_log_enable": "로그 활성화",
@@ -211,6 +230,9 @@
"custom_ip": "사용자 지정 IP",
"blocking_ipv4": "IPv4 차단",
"blocking_ipv6": "IPv6 차단",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "평문 DNS",
"form_enter_rate_limit": "한도 제한 입력하기",
"rate_limit": "한도 제한",
"edns_enable": "EDNS 클라이언트 서브넷 활성화",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Null IP: 제로 IP 주소 (A는 0.0.0.0; AAAA는 ::) 로 응답합니다",
"blocking_mode_custom_ip": "커스텀 IP: 직접 설정한 IP 주소로 응답합니다",
"upstream_dns_client_desc": "이 값을 비워둔다면 AdGuard Home은 <0>DNS 설정</0>에 설정되어 있는 값을 사용합니다.",
"tracker_source": "추적기 소스",
"source_label": "소스",
"found_in_known_domain_db": "알려진 도메인 데이터베이스에서 발견됨.",
"category_label": "카테고리",
"rule_label": "규칙",
"list_label": "목록",
"unknown_filter": "알려지지 않은 필터 {{filterId}}",
"known_tracker": "알려진 추적기",
"install_welcome_title": "AdGuard Home에 오신 것을 환영합니다!",
"install_welcome_desc": "AdGuard Home은 광범위한 네트워크 광고와 추적 DNS 서버를 차단 합니다. 그것의 목적은 당신이 당신의 전체 네트워크와 당신의 모든 기기를 제어하는 것이며, 그것은 클라이언트의 프로그램을 사용할 필요가 없습니다.",
"install_settings_title": "관리자 웹 인터페이스",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "라우터의 환경 설정을 여세요. 환경 설정은 다음의 주소(http://192.168.0.1/ 혹은 http://192.168.1.1/)를 통해 브라우저로 접근 가능합니다. 비밀번호를 입력해야할 수 있습니다. 비밀번호를 잊었다면 대개 라우터 기기에 있는 버튼을 눌러 비밀번호를 초기화할 수 있습니다. 어떤 라우터들은 당신의 컴퓨터/핸드폰에 설치할 수 있는 특정 어플리케이션을 필요로합니다.",
"install_devices_router_list_2": "각각 1~3자리 숫자의 네 그룹으로 분할된 두 세트의 숫자를 허용하는 필드 옆에 있는 DNS 문자를 찾으세요.",
"install_devices_router_list_3": "AdGuard Home 서버 주소를 입력하세요",
"install_devices_router_list_4": "일부 라우터는 DNS서버의 커스텀 설정이 불가합니다. 간혹 AdGuard Home을 DHCP서버로 이용하여 문제를 해결하는 경우가 있지만 문제가 지속될 경우 사용하시는 라우터 모델의 매뉴얼을 참고하시어 DNS서버 커스텀 설정 방법을 직접 살펴보셔야 합니다.",
"install_devices_router_list_4": "일부 라우터는 DNS서버의 커스텀 설정이 불가합니다. 간혹 AdGuard Home을 DHCP서버로 이용하여 문제를 해결하는 경우가 있지만 문제가 지속될 경우 사용하시는 라우터 모델의 매뉴얼을 참고하시어 <0>DNS</0>서버 커스텀 설정 방법을 직접 살펴보셔야 합니다.",
"install_devices_windows_list_1": "시작 메뉴 또는 윈도우 검색을 통해 제어판을 여세요",
"install_devices_windows_list_2": "네트워크 및 인터넷 카테고리로 이동한 다음 네트워크 및 공유 센터로 이동하세요.",
"install_devices_windows_list_3": "화면 왼쪽에서 어댑터 설정 변경을 찾아 클릭하세요.",
@@ -346,6 +370,7 @@
"form_enter_id": "식별자 입력",
"form_add_id": "식별자 추가",
"form_client_name": "클라이언트 이름 입력",
"name": "이름",
"client_global_settings": "글로벌 설정 사용",
"client_deleted": "클라이언트 \"{{key}}\"가 정상적으로 삭제되었습니다",
"client_added": "클라이언트 \"{{key}}\"가 정상적으로 추가되었습니다",
@@ -445,6 +470,7 @@
"location": "위치",
"orgname": "단체 이름",
"netname": "네트워크 이름",
"network": "네트워크",
"descr": "설명",
"whois": "후이즈",
"filtering_rules_learn_more": "차단 리스트를 직접 호스트하는 법을 <0>알아보세요</0>.",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} 리스트 업데이트됨",
"list_updated_plural": "{{count}} 리스트 업데이트됨",
"dnssec_enable": "DNSSEC 활성화",
"dnssec_enable_desc": "발신 DNS 쿼리에서 DNSSEC 플래그를 설정하고 결과를 확인합니다 (DNSSEC-enabled resolver 필수)"
}
"dnssec_enable_desc": "발신 DNS 쿼리에서 DNSSEC 플래그를 설정하고 결과를 확인합니다 (DNSSEC-enabled resolver 필수)",
"validated_with_dnssec": "DNSSEC로 검증됨",
"show_all_responses": "모든 응답",
"show_blocked_responses": "차단됨",
"show_whitelisted_responses": "예외 적용됨",
"show_processed_responses": "처리됨",
"blocked_safebrowsing": "차단된 세이프 브라우징",
"blocked_adult_websites": "차단된 성인 웹사이트",
"blocked_threats": "차단된 위협",
"allowed": "허용됨",
"filtered": "필터링됨",
"rewritten": "재작성됨",
"safe_search": "세이프 서치",
"blocklist": "차단 목록",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Je kan DNS upstream <0>specifiëren voor specifieke domein(en)</0>",
"upstream_parallel": "Gebruik parallelle verzoeken om te versnellen door gelijktijdig verzoeken te sturen naar alle upstream servers",
"parallel_requests": "Parallelle verzoeken",
"load_balancing": "Volume balanceren",
"load_balancing_desc": "Eén server per keer bevragen. AdGuard Home gebruikt hiervoor een gewogen willekeurig algoritme om de server te kiezen zodat de snelste server meer zal gebruikt worden.",
"bootstrap_dns": "Bootstrap DNS servers",
"bootstrap_dns_desc": "Bootstrap DNS-servers worden gebruikt om IP-adressen op te lossen van de DoH / DoT-resolvers die u opgeeft als upstreams.",
"check_dhcp_servers": "Zoek achter DHCP servers",
@@ -26,6 +28,7 @@
"form_error_mac_format": "Ongeldig MAC formaat.",
"form_error_client_id_format": "Opmaak cliënt-ID is ongeldig",
"form_error_positive": "Moet groter zijn dan 0",
"form_error_negative": "Moet 0 of hoger dan 0 zijn",
"dhcp_form_gateway_input": "Gateway IP",
"dhcp_form_subnet_input": "Subnet mask",
"dhcp_form_range_title": "Bereik van IP adressen",
@@ -36,6 +39,7 @@
"dhcp_interface_select": "Selecteer DHCP interface",
"dhcp_hardware_address": "Hardware adres",
"dhcp_ip_addresses": "IP adressen",
"ip": "IP",
"dhcp_table_hostname": "Host naam",
"dhcp_table_expires": "Verloopt op",
"dhcp_warning": "Indien je de ingebouwde DHCP server wilt inschakelen, let dan op dat er geen andere actieve DHCP server aanwezig is. Dit kan de internet verbinding instabiel maken!.",
@@ -48,17 +52,27 @@
"dhcp_static_leases_not_found": "Geen DHCP static lease gevonden",
"dhcp_add_static_lease": "Voeg statische lease toe",
"dhcp_reset": "Weet je zeker dat je de DHCP configuratie wil resetten?",
"country": "Land",
"city": "Stad",
"delete_confirm": "Ben je zeker dat je \"{{key}}\" wilt verwijderen?",
"form_enter_hostname": "Vul hostnaam in",
"error_details": "Fout details",
"response_details": "Antwoorddetails",
"request_details": "Verzoekdetails",
"client_details": "Client details",
"details": "Details",
"back": "Terug",
"dashboard": "Dashboard",
"settings": "Instellingen",
"filters": "Filters",
"filter": "Filter",
"query_log": "Query log",
"compact": "Compact",
"nothing_found": "Niets gevonden",
"faq": "Veel gestelde vragen",
"version": "Versie",
"address": "IP-adres",
"address": "Adres",
"protocol": "Protocol",
"on": "Aan",
"off": "Uit",
"copyright": "Copyright",
@@ -131,8 +145,10 @@
"rules_count_table_header": "Aantal regels",
"last_time_updated_table_header": "Laatste update",
"actions_table_header": "Actie",
"request_table_header": "Verzoek",
"edit_table_action": "Bewerk",
"delete_table_action": "Verwijderen",
"elapsed": "Verstreken",
"filters_and_hosts_hint": "AdGuard Home kan overweg met basic adblock regels en hosts bestanden syntaxis.",
"no_blocklist_added": "Geen blokkeerlijsten toegevoegd",
"no_whitelist_added": "Geen toestemmingslijsten toegevoegd",
@@ -161,20 +177,23 @@
"example_comment_hash": "# Nog een opmerking",
"example_regex_meaning": "blokkeer de toegang tot de domeinen die overeenkomen met de opgegeven reguliere expressie",
"example_upstream_regular": "standaard DNS (over UDP)",
"example_upstream_dot": "versleutelde<a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a>",
"example_upstream_doh": "versleutelde<a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "je kunt <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> voor <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> of <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> resolvers",
"example_upstream_dot": "versleutelde <0>DNS_over_TLS</0>",
"example_upstream_doh": "versleutelde <0>DNS_over_HTTPS</0>",
"example_upstream_sdns": "je kunt <0>DNS Stamps</0> voor <1>DNSCrypt</1> of <2>DNS-over-HTTPS</2> resolvers",
"example_upstream_tcp": "standaard DNS (over TCP)",
"all_lists_up_to_date_toast": "Alle lijsten zijn reeds up-to-date",
"updated_upstream_dns_toast": "De upstream DNS-servers zijn bijgewerkt",
"dns_test_ok_toast": "Opgegeven DNS-servers werken correct",
"dns_test_not_ok_toast": "Server \"{{key}}\": kon niet worden gebruikt, controleer of u het correct hebt geschreven",
"unblock_btn": "Deblokkeer",
"block_btn": "Blokkeer",
"unblock": "Deblokkeren",
"block": "Blokkeren",
"time_table_header": "Tijd",
"date": "Datum",
"domain_name_table_header": "Domein naam",
"domain_or_client": "Domein of cliënt",
"type_table_header": "Type",
"response_table_header": "Antwoord",
"response_code": "Reactie code",
"client_table_header": "Gebruiker",
"empty_response_status": "Leeg",
"show_all_filter_type": "Toon alles",
@@ -193,6 +212,7 @@
"query_log_filtered": "Gefilterd door {{filter}}",
"query_log_confirm_clear": "Weet u zeker dat u het hele query logboek wilt legen?",
"query_log_cleared": "Het query logboek is succesvol geleegd",
"query_log_updated": "Het query logboek is succesvol bijgewerkt",
"query_log_clear": "Leeg query logs",
"query_log_retention": "Query logs bewaartermijn",
"query_log_enable": "Log bestanden inschakelen",
@@ -202,13 +222,37 @@
"query_log_retention_confirm": "Weet u zeker dat u de bewaartermijn van het query logboek wilt wijzigen? Als u de intervalwaarde verlaagt, gaan sommige gegevens verloren",
"anonymize_client_ip": "Cliënt IP anonimiseren",
"anonymize_client_ip_desc": "Het volledige IP-adres van de cliënt niet opnemen in log- en statistiekbestanden",
"dns_config": "DNS server configuratie",
"blocking_mode": "Blocking modus",
"default": "Standaard",
"nxdomain": "NXDOMAIN",
"null_ip": "Nul IP",
"custom_ip": "Aangepast IP",
"blocking_ipv4": "Blokkeren IP4",
"blocking_ipv6": "Blokkeren IP6",
"dns_over_https": "DNS-via-HTTPS",
"dns_over_tls": "DNS-via-TLS",
"plain_dns": "Gewone DNS",
"form_enter_rate_limit": "Voer ratio limiet in",
"rate_limit": "Ratio limiet",
"edns_enable": "Zet EDNS client subnet aan",
"edns_cs_desc": "Indien ingeschakeld stuurt AdGuard Home het subnet van de client naar de DNS-servers.",
"rate_limit_desc": "Het aantal verzoeken per seconde die een enkele client mag doen (0: onbeperkt)",
"blocking_ipv4_desc": "IP-adres dat moet worden teruggegeven voor een geblokkeerd A-verzoek",
"blocking_ipv6_desc": "IP-adres dat moet worden teruggegeven voor een geblokkeerd A-verzoek",
"blocking_mode_default": "Standaard: Reageer met NXDOMAIN wanneer geblokkeerd door een Adblock-type regel; reageer met het IP-adres dat is opgegeven in de regel wanneer het wordt geblokkeerd door een /etc/hosts type regel",
"blocking_mode_nxdomain": "NXDOMAIN: Reageer met NXDOMAIN code",
"blocking_mode_null_ip": "Nul IP: Reageer met een nul IP address (0.0.0.0 voor A; :: voor AAAA)",
"blocking_mode_custom_ip": "Aangepast IP: Reageer met een handmatige ingesteld IP adres",
"upstream_dns_client_desc": "Indien je dit veld leeglaat zal AdGuard Home de servers welke zijn ingesteld in de <0>DNS instellingen</0> gebruiken.",
"tracker_source": "Bron volger",
"source_label": "Bron",
"found_in_known_domain_db": "Gevonden in de bekende domeingegevensbank.",
"category_label": "Categorie",
"rule_label": "Regel",
"list_label": "Lijst",
"unknown_filter": "Onbekend filter {{filterId}}",
"known_tracker": "Bekende volger",
"install_welcome_title": "Welkom bij AdGuard Home!",
"install_welcome_desc": "AdGuard Home is een netwerk DNS server die advertenties en trackers blokkeert. Het doel is om jou controle te geven over je gehele netwerk en al je apparaten, en er hoeft geen client-side programma te worden gebruikt.",
"install_settings_title": "Admin webinterface",
@@ -237,7 +281,7 @@
"install_devices_router_list_1": "Open de instellingen pagina voor uw router. Meestal kunt u deze vanuit uw browser openen via een URL (zoals http://192.168.0.1/ of http://192.168.1.1/). Mogelijk wordt u gevraagd om het wachtwoord in te voeren. Als u het niet meer weet, kunt u het wachtwoord vaak opnieuw instellen door op een knop op de router zelf te drukken. Voor sommige routers is een specifieke toepassing vereist, die in dat geval al op uw computer / telefoon moet zijn geïnstalleerd.",
"install_devices_router_list_2": "Zoek de DHCP/DNS-instellingen. Zoek naar de DNS-letters naast een veld dat twee of drie reeksen nummers toestaat, elk verdeeld in vier groepen van één tot drie cijfers.",
"install_devices_router_list_3": "Voer je AdGuard Home server adressen daar in.",
"install_devices_router_list_4": "Je kan de DNS server niet aanpassen op sommige routers. In dat geval kan het een oplossing zijn om AdGuard Home te definiëren als een DHCP server. Je kan ook in de handleiding van je router kijken hoe je een DNS server aanpast.",
"install_devices_router_list_4": "Je kan de DNS server niet aanpassen op sommige routers. In dat geval kan het een oplossing zijn om AdGuard Home te definiëren als een <0>DHCP server</0>. Je kan ook in de handleiding van je router kijken hoe je een DNS server aanpast.",
"install_devices_windows_list_1": "Open het Configuratiescherm via het menu Start of Windows zoeken.",
"install_devices_windows_list_2": "Ga naar de categorie Netwerk en Internet en vervolgens naar Netwerkcentrum.",
"install_devices_windows_list_3": "Zoek aan de linkerkant van het scherm Adapter-instellingen wijzigen en klik erop.",
@@ -326,6 +370,7 @@
"form_enter_id": "ID invoeren",
"form_add_id": "ID toevoegen",
"form_client_name": "Vul gebruikersnaam in",
"name": "Naam",
"client_global_settings": "Gebruik globale instelling",
"client_deleted": "Gebruiker \"{{key}}\" met succes verwijderd",
"client_added": "Gebruiker \"{{key}}\" met succes toegevoegd",
@@ -425,6 +470,7 @@
"location": "Locatie",
"orgname": "Naam organisatie",
"netname": "Netwerk naam",
"network": "Netwerk",
"descr": "Beschrijving",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Meer informatie</0> over het maken van je eigen host lijsten.",
@@ -433,18 +479,55 @@
"domain_desc": "Voer de domeinnaam of wildcard in die herschreven moet worden.",
"example_rewrite_domain": "herschrijf reacties uitsluitend voor deze domeinnaam.",
"example_rewrite_wildcard": "herschrijf reacties voor alle subdomeinen van <0>example.org</0>.",
"disable_ipv6": "Zet IPv6 uit",
"disable_ipv6_desc": "Als deze functie is ingeschakeld, worden alle DNS-query's voor IPv6-adressen (type AAAA) verwijderd.",
"fastest_addr": "Snelste IP adres",
"fastest_addr_desc": "Alle DNS servers bevragen en het snelste IP adres terugkoppelen",
"fastest_addr_desc": "Alle DNS servers bevragen en het snelste IP adres terugkoppelen. Dit zal de DNS verzoeken vertragen omdat we moeten wachten op de antwoorden van alles DNS servers, maar verbetert wel de connectiviteit.",
"autofix_warning_text": "Als je op \"Repareren\" klikt, configureert AdGuard Home uw systeem om de AdGuard Home DNS-server te gebruiken.",
"autofix_warning_list": "De volgende taken worden uitgevoerd: <0> Deactiveren van Systeem DNSStubListener</0> <0> DNS-serveradres instellen op 127.0.0.1 </0> <0> Symbolisch koppelingsdoel van /etc/resolv.conf vervangen door /run/systemd/resolve/resolv.conf </0> <0> Stop DNSStubListener (herlaad systemd-resolved service) </0>",
"autofix_warning_result": "Als gevolg hiervan worden alle DNS-verzoeken van je systeem standaard door AdGuard Home verwerkt.",
"tags_title": "Labels",
"tags_desc": "Je kunt tags selecteren die overeenkomen met de client. Tags kunnen worden opgenomen in de filterregels en je kunt ze dan nauwkeuriger toepassen. <0> Meer informatie </0>",
"form_select_tags": "Kies client tags",
"check_title": "Controleer de filtering",
"check_desc": "Controleer of de hostnaam wordt gefilterd",
"check": "Controleren",
"form_enter_host": "Voer een hostnaam in",
"filtered_custom_rules": "Gefilterd door aangepaste filterregels",
"host_whitelisted": "De host staat op de toestemmingslijst",
"check_ip": "IP-adressen: {{ip}}",
"check_cname": "CNAME: {{cname}}",
"check_reason": "Reden: {{reason}}",
"check_rule": "Regel: {{rule}}",
"check_service": "Servicenaam: {{service}}",
"check_not_found": "Niet in je lijst met filters gevonden",
"client_confirm_block": "Weet je zeker dat je client \"{{ip}}\" wil blokkeren?",
"client_confirm_unblock": "Weet je zeker dat je client \"{{ip}}\" niet meer wil blokkeren?",
"client_blocked": "Client \"{{ip}}\" wordt nu geblokkeerd",
"client_unblocked": "Client \"{{ip}}\" wordt niet meer geblokkeerd",
"static_ip": "Statisch IP-adres",
"static_ip_desc": "AdGuard Home is een server en heeft daarom een statisch IP-adres nodig om goed te kunnen functioneren, anders kan uw router op een bepaald moment een ander IP-adres aan dit apparaat toewijzen.",
"set_static_ip": "Stel een statisch IP-adres in",
"install_static_ok": "Goed nieuws! Het statische IP-adres was al geconfigureerd",
"install_static_error": "AdGuard Home kan dit niet automatisch configureren op deze netwerkinterface. Zoek een instructie om dit handmatig te doen.",
"install_static_configure": "We hebben vastgesteld dat er een dynamisch IP-adres wordt gebruikt - <0> {{ip}} </0>. Wil je dit als je statische adres gebruiken?",
"confirm_static_ip": "AdGuard Home configureert {{ip}} als jouw statische IP-adres. Wil je doorgaan?",
"list_updated": "{{count}} lijst geüpdatet",
"list_updated_plural": "{{count}} lijsten geüpdatet",
"dnssec_enable": "DNSSEC inschakelen"
"dnssec_enable": "DNSSEC inschakelen",
"dnssec_enable_desc": "Zet de DNSSEC-vlag aan bij uitgaande DNS-query's en controleer het resultaat (DNSSEC-compatibele resolver is vereist)",
"validated_with_dnssec": "Gevalideerd met DNSSEC",
"show_all_responses": "Alle reacties",
"show_blocked_responses": "Geblokkeerd",
"show_whitelisted_responses": "Op toestemmingslijst",
"show_processed_responses": "Verwerkt",
"blocked_safebrowsing": "Geblokkeerd door Veilig Browsen",
"blocked_adult_websites": "Geblokkeerde 18+ websites",
"blocked_threats": "Geblokkeerde bedreigingen",
"allowed": "Toegestaan",
"filtered": "Gefilterd",
"rewritten": "Herschreven",
"safe_search": "Veilig zoeken",
"blocklist": "Blokkeerlijst",
"milliseconds_abbreviation": "ms"
}

View File

@@ -51,14 +51,17 @@
"delete_confirm": "Er du sikker på at du vil slette «{{key}}»?",
"form_enter_hostname": "Skriv inn vertsnavnet",
"error_details": "Feildetaljer",
"request_details": "Detaljer over forespørsel",
"details": "Detaljer",
"back": "Tilbake",
"dashboard": "Kontrollsenter",
"settings": "Innstillinger",
"filters": "Filtre",
"filter": "Filter",
"query_log": "Forespørselslogg",
"faq": "OSS",
"version": "Versjon",
"address": "adresse",
"address": "Adresse",
"on": "PÅ",
"off": "AV",
"copyright": "Opphavsrett",
@@ -167,9 +170,10 @@
"updated_upstream_dns_toast": "Oppdaterte oppstrøms-DNS-tjenerne",
"dns_test_ok_toast": "De spesifiserte DNS-tjenerne fungerer riktig",
"dns_test_not_ok_toast": "Tjeneren «{{key}}» kunne ikke brukes, vennligst dobbeltsjekk at du har skrevet den riktig",
"unblock_btn": "Tillat",
"block_btn": "Blokker",
"unblock": "Tillat",
"block": "Blokker",
"time_table_header": "Tidspunkt",
"date": "Dato",
"domain_name_table_header": "Domenenavn",
"type_table_header": "Type",
"response_table_header": "Respons",
@@ -206,6 +210,7 @@
"custom_ip": "Tilpasset IP",
"blocking_ipv4": "IPv4-blokkering",
"blocking_ipv6": "IPv6-blokkering",
"dns_over_tls": "DNS-over-TLS",
"form_enter_rate_limit": "Skriv inn forespørselsfrekvensgrense",
"rate_limit": "Forespørselsfrekvensgrense",
"edns_enable": "Aktiver EDNS-klientundernett",
@@ -340,6 +345,7 @@
"form_enter_id": "Skriv inn identifikator",
"form_add_id": "Legg til identifikator",
"form_client_name": "Skriv inn klientnavnet",
"name": "Navn",
"client_global_settings": "Bruk de overbestyrte innstillingene",
"client_deleted": "Klienten «{{key}}» ble vellykket slettet",
"client_added": "Klienten «{{key}}» ble vellykket lagt til",
@@ -438,6 +444,7 @@
"location": "Posisjon",
"orgname": "Firmanavn",
"netname": "Nettverksnavn",
"network": "Network",
"descr": "Beskrivelse",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Lær mer</0> om å lage dine egne filterlister for AdGuard Home.",
@@ -478,5 +485,11 @@
"install_static_configure": "Vi har oppdaget at det brukes en dynamisk IP-adresse — <0>{{ip}}</0>. Vil du bruke det som din statiske adresse?",
"confirm_static_ip": "AdGuard Home vil sette opp {{ip}} til å bli din statiske IP-adresse. Vil du fortsette?",
"list_updated": "{{count}} liste oppdatert",
"list_updated_plural": "{{count}} lister oppdatert"
}
"list_updated_plural": "{{count}} lister oppdatert",
"show_blocked_responses": "Blokkért",
"show_processed_responses": "Bearbeidet",
"blocked_adult_websites": "Blokkerte voksennettsteder",
"blocked_threats": "Blokkerte trusler",
"allowed": "Unntak",
"blocklist": "Blokkeringsliste"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "możesz określić serwer DNS <0>dla konkretnych domen</0>",
"upstream_parallel": "Używaj równoległych żądań, aby przyspieszyć rozwiązywanie adresów domen, jednocześnie wysyłając zapytania do wszystkich głównych serwerów DNS",
"parallel_requests": "Równoległe żądania",
"load_balancing": "Równoważenie obciążenia",
"load_balancing_desc": "Zapytaj jeden serwer na raz. AdGuard Home wykorzysta losowy algorytm, aby użyć najczęściej najszybszego serwera.",
"bootstrap_dns": "Serwery DNS Bootstrap",
"bootstrap_dns_desc": "Serwery DNS Bootstrap są używane do ustalenia adresu IP serwerów DoH/DoT, które oznaczysz jako główne serwery DNS.",
"check_dhcp_servers": "Sprawdź serwery DHCP",
@@ -13,8 +15,8 @@
"dhcp_description": "Jeśli router nie zapewnia ustawień DHCP, możesz użyć wbudowanego serwera DHCP AdGuard.",
"dhcp_enable": "Włącz serwer DHCP",
"dhcp_disable": "Wyłącz serwer DHCP",
"dhcp_not_found": "W sieci nie znaleziono aktywnych serwerów DHCP. Bezpiecznie jest włączyć wbudowany serwer DHCP.",
"dhcp_found": "Znaleziono aktywne serwery DHCP odszukane w sieci. Włączenie wbudowanego serwera DHCP nie jest bezpieczne.",
"dhcp_not_found": "Włączenie wbudowanego serwera DHCP jest bezpieczne - nie znaleźliśmy żadnych aktywnych serwerów DHCP w sieci. Sprawdź to jednak ręcznie, ponieważ nasz automatyczny test nie daje obecnie 100% gwarancji.",
"dhcp_found": "W sieci został znaleziony aktywny serwer DHCP. Włączenie wbudowanego serwera DHCP nie jest bezpieczne.",
"dhcp_leases": "Dzierżawa DHCP",
"dhcp_static_leases": "Dzierżawy statyczne DHCP",
"dhcp_leases_not_found": "Nie znaleziono dzierżaw DHCP",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Wybierz interfejs DHCP",
"dhcp_hardware_address": "Adres sprzętowy",
"dhcp_ip_addresses": "Adresy IP",
"ip": "Adres IP",
"dhcp_table_hostname": "Nazwa hosta",
"dhcp_table_expires": "Wygasa",
"dhcp_warning": "Aby włączyć wbudowany serwer DHCP, upewnij się, że nie ma innego aktywnego serwera DHCP. W przeciwnym razie może przerwać połączenie internetowe dla podłączonych urządzeń!",
@@ -49,17 +52,26 @@
"dhcp_static_leases_not_found": "Nie znaleziono statycznych dzierżaw DHCP",
"dhcp_add_static_lease": "Dodaj dzierżawę statyczną",
"dhcp_reset": "Czy na pewno chcesz zresetować konfigurację DHCP?",
"country": "Kraj",
"city": "Miasto",
"delete_confirm": "Czy na pewno chcesz usunąć \"{{key}}\"?",
"form_enter_hostname": "Wpisz nazwę hosta",
"error_details": "Szczegóły błędu",
"response_details": "Szczegóły odpowiedzi",
"request_details": "Szczegóły żądania",
"client_details": "Szczegóły klienta",
"details": "Szczegóły",
"back": "Wróć",
"dashboard": "Panel kontrolny",
"settings": "Ustawienia",
"filters": "Filtry",
"filter": "Filtr",
"query_log": "Dziennik zapytań",
"nothing_found": "Nic nie znaleziono",
"faq": "FAQ",
"version": "wersja",
"address": "adres",
"address": "Adres",
"protocol": "Protokół",
"on": "WŁĄCZONY",
"off": "WYŁĄCZONY",
"copyright": "Prawo autorskie",
@@ -114,26 +126,28 @@
"encryption_settings": "Ustawienia szyfrowania",
"dhcp_settings": "Ustawienia DHCP",
"upstream_dns": "Główne serwery DNS",
"upstream_dns_hint": "Jeśli to pole pozostawisz puste, AdGuard Home wykorzysta usługę<a href='https://www.quad9.net/' target='_blank'>Quad9</a> jako główny serwer DNS.",
"upstream_dns_hint": "Jeśli to pole pozostawisz puste, AdGuard Home wykorzysta usługę <a href='https://www.quad9.net/' target='_blank'>Quad9</a> jako główny serwer DNS.",
"test_upstream_btn": "Test głównych serwerów DNS",
"upstreams": "Główne serwery DNS",
"apply_btn": "Zastosuj",
"disabled_filtering_toast": "Wyłączone filtrowanie",
"enabled_filtering_toast": "Włączone filtrowanie",
"disabled_safe_browsing_toast": "Wyłączone bezpieczne przeglądanie",
"enabled_safe_browsing_toast": "Włączone bezpieczne przeglądanie",
"disabled_safe_browsing_toast": "Bezpieczne przeglądanie zostało wyłączone",
"enabled_safe_browsing_toast": "Bezpieczne przeglądanie zostało włączone",
"disabled_parental_toast": "Wyłączona Kontrola Rodzicielska",
"enabled_parental_toast": "Włączona Kontrola Rodzicielska",
"disabled_safe_search_toast": "Wyłączone bezpieczne wyszukiwanie",
"enabled_save_search_toast": "Włączone bezpieczne wyszukiwanie",
"disabled_safe_search_toast": "Bezpieczne wyszukiwanie zostało włączone",
"enabled_save_search_toast": "Bezpieczne wyszukiwanie zostało włączone",
"enabled_table_header": "Włączone",
"name_table_header": "Nazwa",
"list_url_table_header": "Adres URL listy",
"rules_count_table_header": "Liczba reguł",
"last_time_updated_table_header": "Ostatnia aktualizacja",
"actions_table_header": "Akcje",
"request_table_header": "Żądanie",
"edit_table_action": "Edytuj",
"delete_table_action": "Usuń",
"elapsed": "Upłynęło",
"filters_and_hosts_hint": "AdGuard Home rozumie podstawowe reguły adblocka i składnię plików hostów.",
"no_blocklist_added": "Nie dodano listy zablokowanych",
"no_whitelist_added": "Nie dodano listy dozwolonych",
@@ -164,18 +178,21 @@
"example_upstream_regular": "normalny DNS (przez UDP)",
"example_upstream_dot": "zaszyfrowany <0>DNS-over-TLS</0>",
"example_upstream_doh": "zaszyfrowany <0>DNS-over-HTTPS</0>",
"example_upstream_sdns": "możesz użyć adresu<0>DNS Stamps</0> dla protokołu <1>DNSCrypt</1> lub <2>DNS-over-HTTPS</2>",
"example_upstream_sdns": "możesz użyć adresu <0>DNS Stamps</0> dla protokołu <1>DNSCrypt</1> lub <2>DNS-over-HTTPS</2>",
"example_upstream_tcp": "zwykły DNS (przez TCP)",
"all_lists_up_to_date_toast": "Wszystkie listy są już aktualne",
"updated_upstream_dns_toast": "Główne serwery DNS zostały zaktualizowane",
"dns_test_ok_toast": "Określone serwery DNS działają poprawnie",
"dns_test_not_ok_toast": "Serwer \"{{key}}\": nie można go użyć, sprawdź, czy napisałeś go poprawnie",
"unblock_btn": "Odblokuj",
"block_btn": "Zablokuj",
"unblock": "Odblokuj",
"block": "Zablokuj",
"time_table_header": "Czas",
"date": "Data",
"domain_name_table_header": "Nazwa domeny",
"domain_or_client": "Domena lub klient",
"type_table_header": "Typ",
"response_table_header": "Odpowiedź ",
"response_code": "Kod odpowiedzi",
"client_table_header": "Klient",
"empty_response_status": "Pusty",
"show_all_filter_type": "Pokaż wszystko",
@@ -211,6 +228,9 @@
"custom_ip": "Niestandardowy adres IP",
"blocking_ipv4": "Blokowanie IPv4",
"blocking_ipv6": "Blokowanie IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "Zwykły DNS",
"form_enter_rate_limit": "Wpisz limit ilościowy",
"rate_limit": "Limit ilościowy",
"edns_enable": "Włącz podsieć klienta EDNS",
@@ -229,7 +249,8 @@
"rule_label": "Reguła",
"list_label": "Lista",
"unknown_filter": "Nieznany filtr {{filterId}}",
"install_welcome_title": "Witamy w AdGuard Home!",
"known_tracker": "Znany element śledzący",
"install_welcome_title": "Witaj w AdGuard Home!",
"install_welcome_desc": "AdGuard Home to w pełni funkcjonalny serwer DNS do blokowania reklam i śledzenia. Jego celem jest kontrolowanie całej sieci i wszystkich urządzeń, bez konieczności korzystania z jakiegokolwiek programu po stronie klienta.",
"install_settings_title": "Interfejs internetowy administratora",
"install_settings_listen": "Interfejs sieciowy",
@@ -257,7 +278,7 @@
"install_devices_router_list_1": "Otwórz ustawienia routera. Zazwyczaj możesz uzyskać do niego dostęp przez przeglądarkę za pośrednictwem adresu URL (na przykład http://192.168.0.1/ lub http://192.168.1.1/). Możesz zostać poproszony o wpisanie hasła. Jeśli nie pamiętasz hasła, możesz je odzyskać, naciskając przycisk na samym routerze. Niektóre routery wymagają określonej aplikacji, która powinna być już zainstalowana na komputerze lub telefonie.",
"install_devices_router_list_2": "Znajdź ustawienia DHCP/DNS. Poszukaj skrótu DNS obok pola, które pozwala wstawić dwa lub trzy zestawy liczb, z których każdy jest podzielony na cztery grupy z jedną do trzech cyfr.",
"install_devices_router_list_3": "Wpisz adresy swojego serwera AdGuard Home.",
"install_devices_router_list_4": "Nie możesz ustawić niestandardowego serwera DNS na niektórych routerach. W takim przypadku może pomóc Ci skonfigurowanie AdGuard Home jako serwera DHCP. W przeciwnym razie musisz poszukać instrukcji ustawienia serwerów DNS dla konkretnego modelu routera.",
"install_devices_router_list_4": "Nie możesz ustawić niestandardowego serwera DNS na niektórych routerach. W takim przypadku może pomóc Ci skonfigurowanie AdGuard Home jako <0>serwera DHCP</0>. W przeciwnym razie musisz poszukać instrukcji ustawienia serwerów DNS dla konkretnego modelu routera.",
"install_devices_windows_list_1": "Otwórz panel Ustawienia w menu Start lub w Windows.",
"install_devices_windows_list_2": "Przejdź do kategorii Sieć i Internet, a następnie do Centrum sieci i udostępniania.",
"install_devices_windows_list_3": "Po lewej stronie ekranu znajdź Zmień ustawienia adaptera i kliknij na niego.",
@@ -301,7 +322,7 @@
"encryption_key": "Klucz prywatny",
"encryption_key_input": "Tutaj kopiuj/wklej klucze prywatne zakodowane w PEM do swojego certyfikatu.",
"encryption_enable": "Włącz szyfrowanie (HTTPS, DNS-over-HTTPS i DNS-over-TLS)",
"encryption_enable_desc": "Jeśli szyfrowanie jest włączone, interfejs administracyjny AdGuard Home będzie działał przez HTTPS, a serwer DNS będzie nasłuchiwał żądań przez DNS-overHTTPS i DNS-over-TLS.",
"encryption_enable_desc": "Jeśli szyfrowanie jest włączone, interfejs administracyjny AdGuard Home będzie działał przez HTTPS, a serwer DNS będzie nasłuchiwał żądań przez DNS-over-HTTPS i DNS-over-TLS.",
"encryption_chain_valid": "Łańcuch certyfikatów jest prawidłowy",
"encryption_chain_invalid": "Łańcuch certyfikatu jest nieprawidłowy",
"encryption_key_valid": "Poprawny {{type}} klucz prywatny.",
@@ -346,6 +367,7 @@
"form_enter_id": "Wpisz identyfikator",
"form_add_id": "Dodaj identyfikator",
"form_client_name": "Wpisz nazwę klienta",
"name": "Nazwa",
"client_global_settings": "Użyj ustawień globalnych",
"client_deleted": "Klient \"{{key}}\" został pomyślnie usunięty",
"client_added": "Klient \"{{key}}\" został pomyślnie dodany",
@@ -445,6 +467,7 @@
"location": "Lokalizacja",
"orgname": "Nazwa firmy",
"netname": "Nazwa sieci",
"network": "Sieć",
"descr": "Opis",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Dowiedz się więcej</0> o tworzeniu własnych list blokowania hostów.",
@@ -455,8 +478,8 @@
"example_rewrite_wildcard": "przepisz odpowiedzi dla wszystkich subdomen <0>example.org</0>.",
"disable_ipv6": "Wyłącz IPv6",
"disable_ipv6_desc": "Jeśli ta funkcja jest włączona, wszystkie zapytania DNS dotyczące adresów IPv6 (typ AAAA) zostaną usunięte.",
"fastest_addr": "Szybszy adres IP",
"fastest_addr_desc": "Zapytaj wszystkie serwery DNS i zwróć najszybszy adres IP spośród wszystkich odpowiedzi",
"fastest_addr": "Najszybszy adres IP",
"fastest_addr_desc": "Zapytaj wszystkie serwery DNS i zwróć najszybszy adres IP spośród wszystkich odpowiedzi. Ta czynność spowolni zapytania DNS, ponieważ odpowiedź musi nadejść ze wszystkich serwerów DNS, ale poprawi ogólną stabilność połączenia.",
"autofix_warning_text": "Jeśli klikniesz „Napraw”, AdGuardHome skonfiguruje system do korzystania z serwera DNS AdGuardHome.",
"autofix_warning_list": "Wykona następujące zadania: <0>Dezaktywuj system DNSStubListener</0> <0>Ustaw adres serwera DNS na 127.0.0.1</0> <0>Zamień symboliczny cel łącza z /etc/resolv.conf na /run/systemd/resolve/resolv.conf</0> <0>Zatrzymaj DNSStubListener (przeładuj usługę systemową)</0>",
"autofix_warning_result": "W rezultacie wszystkie żądania DNS z Twojego systemu będą domyślnie przetwarzane przez AdGuardHome.",
@@ -489,5 +512,19 @@
"list_updated": "{{count}} lista zaktualizowana",
"list_updated_plural": "{{count}} list zaktualizowanych",
"dnssec_enable": "Włącz DNSSEC",
"dnssec_enable_desc": "Ustaw flagę DNSSEC w wychodzących zapytaniach DNS i sprawdź wynik (wymagany jest resolver z obsługą zabezpieczania DNSSEC)"
}
"dnssec_enable_desc": "Ustaw flagę DNSSEC w wychodzących zapytaniach DNS i sprawdź wynik (wymagany jest usługodawca z obsługą zabezpieczania DNSSEC)",
"validated_with_dnssec": "Zweryfikowany przez DNSSEC",
"show_all_responses": "Wszystkie odpowiedzi",
"show_blocked_responses": "Zablokowane",
"show_whitelisted_responses": "Biała lista",
"show_processed_responses": "Przetworzono",
"blocked_safebrowsing": "Zablokowane przez bezpieczne przeglądanie",
"blocked_adult_websites": "Zablokowane witryny dla dorosłych",
"blocked_threats": "Zablokowane zagrożenia",
"allowed": "Dozwolone",
"filtered": "Filtrowane",
"rewritten": "Przepisane",
"safe_search": "Bezpieczne wyszukiwanie",
"blocklist": "Lista zablokowanych",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Você pode especificar o DNS upstream <0>para o domínio(s) especifico</0>",
"upstream_parallel": "Usar consultas paralelas para acelerar a resolução consultando simultaneamente todos os servidores upstream",
"parallel_requests": "Solicitações paralelas",
"load_balancing": "Balanceamento de carga",
"load_balancing_desc": "Consulta um servidor de cada vez. O AdGuard Home usará o algoritmo aleatório ponderado para escolher o servidor, para que o servidor mais rápido seja usado com mais frequência.",
"bootstrap_dns": "Servidores DNS de inicialização",
"bootstrap_dns_desc": "Servidores DNS de inicialização são usados para resolver endereços IP dos resolvedores DoH/DoT que você especifica como upstreams.",
"check_dhcp_servers": "Verificar por servidores DHCP",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Selecione a interface DHCP",
"dhcp_hardware_address": "Endereço de hardware",
"dhcp_ip_addresses": "Endereço de IP",
"ip": "IP",
"dhcp_table_hostname": "Nome do servidor",
"dhcp_table_expires": "Expira",
"dhcp_warning": "Se você quiser ativar o servidor DHCP, verifique se não há outro servidor DHCP ativo na sua rede. Caso contrário, a internet pode parar de funcionar para outros dispositivos conectados!",
@@ -49,17 +52,25 @@
"dhcp_static_leases_not_found": "Nenhuma concessão DHCP estática foi encontrada",
"dhcp_add_static_lease": "Adicionar nova concessão estática",
"dhcp_reset": "Você tem certeza de que deseja redefinir a configuração DHCP?",
"country": "País",
"city": "Cidade",
"delete_confirm": "Você tem certeza de que deseja excluir \"{{key}}\"?",
"form_enter_hostname": "Digite o hostname",
"error_details": "Detalhes do erro",
"response_details": "Detalhes da resposta",
"request_details": "Detalhes da solicitação",
"client_details": "Detalhes do cliente",
"details": "Detalhes",
"back": "Voltar",
"dashboard": "Painel",
"settings": "Configurações",
"filters": "Filtros",
"filter": "Filtro",
"query_log": "Registro de consultas",
"faq": "FAQ",
"version": "Versão",
"address": "endereço",
"address": "Endereço",
"protocol": "Protocolo",
"on": "Ligado",
"off": "Desligado",
"copyright": "Copyright",
@@ -132,8 +143,10 @@
"rules_count_table_header": "Quantidade de regras",
"last_time_updated_table_header": "Última atualização",
"actions_table_header": "Ações",
"request_table_header": "Solicitação",
"edit_table_action": "Editar",
"delete_table_action": "Excluir",
"elapsed": "Tempo decorrido",
"filters_and_hosts_hint": "O AdGuard Home entende regras básicas de bloqueio de anúncios e a sintaxe de arquivos de hosts.",
"no_blocklist_added": "Nenhuma lista negra foi adicionada",
"no_whitelist_added": "Nenhuma lista branca foi adicionada",
@@ -170,10 +183,12 @@
"updated_upstream_dns_toast": "Atualizado os servidores DNS upstream",
"dns_test_ok_toast": "Os servidores DNS especificados estão funcionando corretamente",
"dns_test_not_ok_toast": "O servidor \"{{key}}\": não pôde ser utilizado. Por favor, verifique se você escreveu corretamente",
"unblock_btn": "Desbloquear",
"block_btn": "Bloquear",
"unblock": "Desbloquear",
"block": "Bloquear",
"time_table_header": "Data",
"date": "Data",
"domain_name_table_header": "Nome de domínio",
"domain_or_client": "Domínio ou cliente",
"type_table_header": "Tipo",
"response_table_header": "Resposta",
"client_table_header": "Cliente",
@@ -211,6 +226,9 @@
"custom_ip": "IP personalizado",
"blocking_ipv4": "Bloqueando IPv4",
"blocking_ipv6": "Bloqueando IPv6",
"dns_over_https": "DNS-sobre-HTTPS",
"dns_over_tls": "DNS-sobre-TLS",
"plain_dns": "DNS simples",
"form_enter_rate_limit": "Insira a taxa limite",
"rate_limit": "Taxa limite",
"edns_enable": "Ativar a sub-rede do cliente EDNS",
@@ -229,6 +247,7 @@
"rule_label": "Regra",
"list_label": "Lista",
"unknown_filter": "Filtro desconhecido {{filterId}}",
"known_tracker": "Rastreador conhecido",
"install_welcome_title": "Bem-vindo(a) ao AdGuard Home!",
"install_welcome_desc": "O AdGuard Home é um servidor de DNS para bloqueio de anúncios e rastreamento em toda a rede. Sua finalidade é permitir que você controle toda a sua rede e seus dispositivos sem precisar ter um programa instalado.",
"install_settings_title": "Interface web de administrador",
@@ -257,7 +276,7 @@
"install_devices_router_list_1": "Abra as configurações do seu roteador\nNo navegador digite o IP do roteador, o padrão é (http://192.168.0.1/ ou http://192.168.1.1/), e o login e senha é admin/admin; Se você não se lembra da senha, você pode redefinir a senha rapidamente pressionando um botão no próprio roteador. Alguns roteadores têm um aplicativo específico que já deve estar instalado em seu computador/telefone.",
"install_devices_router_list_2": "Encontre as Configurações de DNS. Procure as letras DNS ao lado de um campo que permite dois ou três conjuntos de números, cada um dividido em quatro grupos de um a três números.",
"install_devices_router_list_3": "Digite aqui seu servidor do AdGuard Home.",
"install_devices_router_list_4": "Você não pode definir um servidor DNS personalizado em alguns tipos de roteadores. Nesse caso, pode ajudar se você configurar o AdGuard Home como um servidor DHCP. Caso contrário, você deve procurar o manual sobre como personalizar os servidores DNS para o seu modelo de roteador específico.",
"install_devices_router_list_4": "Você não pode definir um servidor DNS personalizado em alguns tipos de roteadores. Nesse caso, pode ajudar se você configurar o AdGuard Home como um <0>servidor DHCP</0>. Caso contrário, você deve procurar o manual sobre como personalizar os servidores DNS para o seu modelo de roteador específico.",
"install_devices_windows_list_1": "Abra o Painel de Controle pelo Menu Iniciar ou pela Pesquisa do Windows.",
"install_devices_windows_list_2": "Entre na categoria Rede e Internet e depois clique em Central de Rede e Compartilhamento.",
"install_devices_windows_list_3": "No lado esquerdo da janela clique em Alterar as configurações do adaptador.",
@@ -346,6 +365,7 @@
"form_enter_id": "Inserir identificador",
"form_add_id": "Adicionar identificador",
"form_client_name": "Digite o nome do cliente",
"name": "Nome",
"client_global_settings": "Usar configurações global",
"client_deleted": "Cliente \"{{key}}\" excluído com sucesso",
"client_added": "Cliente \"{{key}}\" adicionado com sucesso",
@@ -445,6 +465,7 @@
"location": "Localização",
"orgname": "Nome da organização",
"netname": "Nome da rede",
"network": "Rede",
"descr": "Descrição",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Saiba mais</0> sobre como criar as suas próprias listas negras de servidores.",
@@ -456,7 +477,7 @@
"disable_ipv6": "Desativar IPv6",
"disable_ipv6_desc": "Se este recurso estiver ativado, todas as consultas de DNS para endereços IPv6 (tipo AAAA) serão ignoradas.",
"fastest_addr": "Endereço de IP mais rápido",
"fastest_addr_desc": "Consulte todos os servidores de DNS e retorne o endereço de IP mais rápido entre todas as respostas",
"fastest_addr_desc": "Consulta todos os servidores DNS e retorna o endereço IP mais rápido entre todas as respostas. Isso irá retardar as consultas ao DNS, pois temos que esperar por respostas de todos os servidores DNS, porém melhorando a conectividade em geral.",
"autofix_warning_text": "Se clicar em \"Corrigir\", o AdGuardHome irá configurar o seu sistema para utilizar o servidor DNS do AdGuardHome.",
"autofix_warning_list": "Ele irá realizar estas tarefas: <0>Desativar sistema DNSStubListener</0> <0>Definir endereço do servidor DNS para 127.0.0.1</0> <0>Substituir o alvo simbólico do link /etc/resolv.conf para /run/systemd/resolv.conf</0> <0>Parar DNSStubListener (recarregar serviço resolvido pelo sistema)</0>",
"autofix_warning_result": "Como resultado, todos as solicitações DNS do seu sistema serão processadas pelo AdGuardHome por padrão.",
@@ -489,5 +510,19 @@
"list_updated": "{{count}} lista atualizada",
"list_updated_plural": "{{count}} listas atualizadas",
"dnssec_enable": "Ativar DNSSEC",
"dnssec_enable_desc": "Definir a flag DNSSEC nas consultas de DNS em andamento e verificar o resultado (é necessário um resolvedor DNSSEC ativado)"
"dnssec_enable_desc": "Definir a flag DNSSEC nas consultas de DNS em andamento e verificar o resultado (é necessário um resolvedor DNSSEC ativado)",
"validated_with_dnssec": "Validado com DNSSEC",
"show_all_responses": "Todas as respostas",
"show_blocked_responses": "Bloqueado",
"show_whitelisted_responses": "Na lista branca",
"show_processed_responses": "Processado",
"blocked_safebrowsing": "Bloqueado pela navegação segura",
"blocked_adult_websites": "Sites adultos bloqueados",
"blocked_threats": "Ameaças bloqueadas",
"allowed": "Permitido",
"filtered": "Filtrado",
"rewritten": "Reescrito",
"safe_search": "Pesquisa segura",
"blocklist": "Lista negra",
"milliseconds_abbreviation": "ms"
}

View File

@@ -58,7 +58,7 @@
"query_log": "Registo de consultas",
"faq": "Perguntas frequentes",
"version": "Versão",
"address": "endereço",
"address": "Endereço",
"on": "LIGADO",
"off": "DESLIGADO",
"copyright": "Copyright",
@@ -149,9 +149,10 @@
"updated_upstream_dns_toast": "A actualizar os servidores DNS upstream",
"dns_test_ok_toast": "Os servidores DNS especificados estão a funcionar correctamente",
"dns_test_not_ok_toast": "O servidor \"{{key}}\": não pôde ser utilizado. Por favor, verifique se o escreveu correctamente",
"unblock_btn": "Desbloquear",
"block_btn": "Bloquear",
"unblock": "Desbloquear",
"block": "Bloquear",
"time_table_header": "Data",
"date": "Data",
"domain_name_table_header": "Nome do domínio",
"type_table_header": "Tipo",
"response_table_header": "Resposta",
@@ -316,6 +317,7 @@
"form_enter_id": "Inserir identificador",
"form_add_id": "Adicionar identificador",
"form_client_name": "Insira o nome do cliente",
"name": "Nome",
"client_global_settings": "Usar configurações globais",
"client_deleted": "Cliente \"{{key}}\" excluído com sucesso",
"client_added": "Cliente \"{{key}}\" adicionado com sucesso",
@@ -412,6 +414,7 @@
"location": "Localização",
"orgname": "Nome da organização",
"netname": "Nome da rede",
"network": "Network",
"descr": "Descrição",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Saiba mais</0>sobre como criar as suas próprias listas negras de servidores.",
@@ -419,5 +422,9 @@
"try_again": "Tente novamente",
"domain_desc": "Insere o nome do domínio para ser reescrito.",
"example_rewrite_domain": "reescrever resposta apenas para este domínio.",
"example_rewrite_wildcard": "reescrever resposta para todos <0>example.org</0> sub-domínios."
"example_rewrite_wildcard": "reescrever resposta para todos <0>example.org</0> sub-domínios.",
"form_enter_host": "Insira o hostname",
"show_blocked_responses": "Bloqueado",
"show_whitelisted_responses": "Lista Branca",
"show_processed_responses": "Processado"
}

View File

@@ -1,8 +1,10 @@
{
"client_settings": "Setări client",
"example_upstream_reserved": "Puteți preciza un DNS upstream <0>de domeni/u(ii) specific(e)</0>",
"example_upstream_reserved": "Puteți preciza un DNS upstream <0>de domeniu(ii) specific(e)</0>",
"upstream_parallel": "Folosiți interogări paralele pentru rezolvări rapide interogând simultan toate serverele în amonte",
"parallel_requests": "Solicitări paralele",
"load_balancing": "Echilibrare-sarcini",
"load_balancing_desc": "Fiecare server este interogat aparte. AdGuard Home alege serverul folosind algoritmul ponderat aleatoriu, astfel încât cel mai rapid server să fie utilizat mai des.",
"bootstrap_dns": "Serverele DNS Bootstrap",
"bootstrap_dns_desc": "Serverele DNS Bootstrap sunt folosite pentru a rezolva adresele IP ale resolverelor DoH/DoT indicate ca upstreams.",
"check_dhcp_servers": "Căutați servere DHCP",
@@ -20,11 +22,11 @@
"dhcp_leases_not_found": "Nu s-au găsit DHCP închiriate",
"dhcp_config_saved": "Configurare DHCP salvată cu succes",
"form_error_required": "Câmp necesar",
"form_error_ip4_format": "Format IPv4 nevalid",
"form_error_ip6_format": "Format IPv6 nevalid",
"form_error_ip_format": "Format IP nevalid",
"form_error_mac_format": "Format MAC nevalid",
"form_error_client_id_format": "Format ID de client nevalid",
"form_error_ip4_format": "Format IPv4 invalid",
"form_error_ip6_format": "Format IPv6 invalid",
"form_error_ip_format": "Format IP invalid",
"form_error_mac_format": "Format MAC invalid",
"form_error_client_id_format": "Format ID de client invalid",
"form_error_positive": "Trebuie să fie mai mare de 0",
"form_error_negative": "Trebuie să fie egală cu 0 sau mai mare",
"dhcp_form_gateway_input": "IP Gateway",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Selectați interfața DHCP",
"dhcp_hardware_address": "Adresa mașinii",
"dhcp_ip_addresses": "Adrese IP",
"ip": "IP",
"dhcp_table_hostname": "Hostname",
"dhcp_table_expires": "Expiră",
"dhcp_warning": "Dacă doriți oricum să activați serverul DHCP, verificați că nu există un alt server DHCP activ în rețeaua dvs. Altfel, poate întrerupe Internetul pe toate aparatele conectate!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "Nu s-au găsit închirieri statice DHCP",
"dhcp_add_static_lease": "Adăugați închiriere statică",
"dhcp_reset": "Sunteți sigur că doriți să resetați configurația DHCP?",
"country": "Țara",
"city": "Oraș",
"delete_confirm": "Sunteți sigur că doriți să ștergeți \"{{key}}\"?",
"form_enter_hostname": "Intrați hostname",
"form_enter_hostname": "Introduceți hostname",
"error_details": "Detalii eroare",
"response_details": "Detalii răspuns",
"request_details": "Detalii solicitare",
"client_details": "Detalii client",
"details": "Detalii",
"back": "Înapoi",
"dashboard": "Tablou de bord",
"settings": "Setări",
"filters": "Filtre",
"filter": "Filtru",
"query_log": "Jurnal interogări",
"compact": "Compact",
"nothing_found": "Nimic găsit",
"faq": "FAQ",
"version": "Versiune",
"address": "adresă",
"address": "Adresă",
"protocol": "Protocol",
"on": "ON",
"off": "OFF",
"copyright": "Copyright",
@@ -77,7 +90,7 @@
"stats_adult": "Site-uri cu conținut adult blocate",
"stats_query_domain": "Domeniile cele mai căutate",
"for_last_24_hours": "în ultimele 24 ore",
"for_last_days": "în ultimele {{count}} zile",
"for_last_days": "în ultima {{count}} zi",
"for_last_days_plural": "pentru ultimele {{count}} zile",
"no_domains_found": "Nu s-au găsit domenii",
"requests_count": "Cont interogări",
@@ -99,8 +112,8 @@
"filters_block_toggle_hint": "Puteți configura regulile de blocare în setările <a href='#filters'> Filtre </a>.",
"use_adguard_browsing_sec": "Utilizați serviciul Navigarea în Securitate AdGuard",
"use_adguard_browsing_sec_hint": "AdGuard Home va verifica dacă domeniul este în lista negră a serviciul web de securitate de navigare. Pentru acesta va utiliza un lookup API discret: un prefix scurt al numelui de domeniu SHA256 hash este trimis serverului.",
"use_adguard_parental": "Utilizați controlul parental AdGuard",
"use_adguard_parental_hint": "AdGuard Home va verifica dacă este conținut adult pe domeniu. Utilizează aceeași API discret ca cel utilizat de serviciul de securitate de navigare.",
"use_adguard_parental": "Utilizați Controlul Parental AdGuard",
"use_adguard_parental_hint": "AdGuard Home va verifica pentru conținut adult pe domeniu. Utilizează același API discret ca cel utilizat de serviciul de securitate de navigare.",
"enforce_safe_search": "Căutare protejată întărită",
"enforce_save_search_hint": "AdGuard Home poate impune căutarea protejată în următoarele motoare de căutare: Google, Youtube, Bing, DuckDuckGo, Yandex, Pixabay.",
"no_servers_specified": "Nu sunt specificate servere",
@@ -120,8 +133,8 @@
"apply_btn": "Aplică",
"disabled_filtering_toast": "Filtrare dezactivată",
"enabled_filtering_toast": "Filtrare activată",
"disabled_safe_browsing_toast": "Navigare protejată dezactivată",
"enabled_safe_browsing_toast": "Navigare protejată activată",
"disabled_safe_browsing_toast": "Navigare securitară dezactivată",
"enabled_safe_browsing_toast": "Navigare securitară activată",
"disabled_parental_toast": "Control parental dezactivat",
"enabled_parental_toast": "Control parental activat",
"disabled_safe_search_toast": "Căutare protejată dezactivată",
@@ -132,50 +145,55 @@
"rules_count_table_header": "Număr de reguli",
"last_time_updated_table_header": "Ultima aducere la zi",
"actions_table_header": "Acțiuni",
"request_table_header": "Solicitare",
"edit_table_action": "Editare",
"delete_table_action": "Sterge",
"delete_table_action": "Șterge",
"elapsed": "Scurs",
"filters_and_hosts_hint": "AdGuard Home înțelege regulile de bază de blocare cât și sintaxa fișierelor hosts.",
"no_blocklist_added": "Listă blocări goală",
"no_whitelist_added": "Listă autorizări goală",
"add_blocklist": "Adăugați blocaj",
"add_allowlist": "Adăugați autorizare",
"cancel_btn": "Anulare",
"enter_name_hint": "Intrați numele",
"enter_url_or_path_hint": "Intrați un URL sau o cale absolută a listei",
"enter_name_hint": "Introduceți numele",
"enter_url_or_path_hint": "Introduceți un URL sau o cale absolută a listei",
"check_updates_btn": "Caută actualizări",
"new_blocklist": "Nouă blocare",
"new_allowlist": "Nouă autorizare",
"edit_blocklist": "Editare blocare",
"edit_allowlist": "Editare autorizare",
"enter_valid_blocklist": "Intrați un URL valid pentru blocare.",
"enter_valid_allowlist": "Intrați un URL valid pentru autorizare.",
"enter_valid_blocklist": "Introduceți un URL valid pentru blocare.",
"enter_valid_allowlist": "Introduceți un URL valid pentru autorizare.",
"form_error_url_format": "Format URL invalid",
"form_error_url_or_path_format": "Invalid URL sau o cale absolută a listei",
"custom_filter_rules": "Reguli de filtrare personalizate",
"custom_filter_rules_hint": "Intrați o regulă pe linie. Puteți utiliza reguli de blocare sau sintaxa de fișiere hosts.",
"custom_filter_rules_hint": "Introduceți o regulă pe linie. Puteți utiliza reguli de blocare sau sintaxa de fișiere hosts.",
"examples_title": "Exemple",
"example_meaning_filter_block": "blochează accesul la domeniul exemplu.org și la toate subdomeniile sale",
"example_meaning_filter_whitelist": "deblochează accesul la domeniul exemplu.org și la toate subdomeniile sale",
"example_meaning_host_block": "AdGuard Home va returna acum adresa 127.0.0.1 pentru domeniul example.org (dar nu și subdomeniile sale).",
"example_meaning_host_block": "AdGuard Home va returna acum adresa 127.0.0.1 pentru domeniul exemplu.org (dar nu și subdomeniile sale).",
"example_comment": "! Iată cum se adăugă o descriere",
"example_comment_meaning": "comentariu",
"example_comment_hash": "# Astfel putem lăsa comentarii",
"example_regex_meaning": "blocare acces la domenii care corespund expresiei obișnuite specificate",
"example_upstream_regular": "DNS clasic (peste UDP)",
"example_upstream_regular": "DNS clasic (over UDP)",
"example_upstream_dot": "<0>DNS-over-TLS</0> criptat",
"example_upstream_doh": "<0>DNS-over-HTTPS</0> criptat",
"example_upstream_sdns": "puteți utiliza <0>DNS Stamps</0> pentru rezolvere <1>DNSCrypt</1> sau <2>DNS-over-HTTPS</2>",
"example_upstream_tcp": "DNS clasic (peste TCP)",
"example_upstream_tcp": "DNS clasic (over TCP)",
"all_lists_up_to_date_toast": "Toate listele sunt deja la zi",
"updated_upstream_dns_toast": "Serverele DNS upstream aduse la zi",
"dns_test_ok_toast": "Serverele DNS specificate funcționează corect",
"dns_test_not_ok_toast": "Serverul \"{{key}}\": nu a putut fi utilizat, verificați dacă l-ați scris corect",
"unblock_btn": "Deblocați",
"block_btn": "Blocați",
"unblock": "Deblocați",
"block": "Blocați",
"time_table_header": "Ora",
"date": "Data",
"domain_name_table_header": "Nume domeniu",
"domain_or_client": "Domeniu sau client",
"type_table_header": "Tip",
"response_table_header": "Răspuns",
"response_code": "Cod de răspuns",
"client_table_header": "Client",
"empty_response_status": "Gol",
"show_all_filter_type": "Arată tot",
@@ -189,11 +207,12 @@
"rows_table_footer_text": "linii",
"updated_custom_filtering_toast": "Reguli personalizate de filtrare aduse la zi",
"rule_removed_from_custom_filtering_toast": "Regulă scoasă din regullei personalizate de filtrare",
"rule_added_to_custom_filtering_toast": "Regula adăugată la regulile de filtrare personalizate",
"rule_added_to_custom_filtering_toast": "Regulă adăugată la regulile de filtrare personalizate",
"query_log_response_status": "Statut: {{value}}",
"query_log_filtered": "Filtrat de {{filter}}",
"query_log_confirm_clear": "Sunteți sigur că doriți să ștergeți întregul jurnal de interogări?",
"query_log_cleared": "Jurnalul de interogare a fost șters cu succes",
"query_log_updated": "Jurnalul de solicitări a fost actualizat cu succes",
"query_log_clear": "Curăță jurnalele",
"query_log_retention": "Retenție jurnale interogare",
"query_log_enable": "Activați jurnal",
@@ -211,31 +230,36 @@
"custom_ip": "IP personalizat",
"blocking_ipv4": "Blocarea IPv4",
"blocking_ipv6": "Blocarea IPv6",
"form_enter_rate_limit": "Intrați limita ratei",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "DNS simplu",
"form_enter_rate_limit": "Introduceți limita ratei",
"rate_limit": "Limita ratei",
"edns_enable": "Activați clientul subnet EDNS",
"edns_cs_desc": "Dacă este activat, AdGuard Home va trimite subnet-ele clienților către serverele DNS.",
"edns_cs_desc": "Dacă este activat, AdGuard Home va trimite subnet-ul clienților către serverele DNS.",
"rate_limit_desc": "Numărul de solicitări pe secundă pe care un singur client este permis să le facă (0: nelimitat)",
"blocking_ipv4_desc": "Adresa IP de returnat pentru o cerere A de blocare",
"blocking_ipv6_desc": "Adresa IP de returnat pentru o cerere AAAA de blocare",
"blocking_mode_default": "Implicit: Răspunde cu NXDOMAIN cînd sunt blocate de regula Adblock-style; răspunde cu adresa IP specificată în regulă când sunt blocate de regula /etc/hosts-style",
"blocking_mode_default": "Implicit: Răspunde cu NXDOMAIN când sunt blocate de regulă tip Adblock; răspunde cu adresa IP specificată în regulă când sunt blocate de regula tip /etc/hosts",
"blocking_mode_nxdomain": "NXDOMAIN: Răspunde cu codul NXDOMAIN",
"blocking_mode_null_ip": "IP nul: răspunde cu o adresă IP zero (0.0.0.0 pentru A; :: pentru AAAA)",
"blocking_mode_custom_ip": "IP personalizat: răspunde cu o adresă IP setată manual",
"upstream_dns_client_desc": "Dacă mențineți acest câmp gol, AdGuard Home va folosi serverele configurate în <0>setările DNS</0>.",
"tracker_source": "Sursă tracker",
"source_label": "Sursă",
"found_in_known_domain_db": "Găsit în baza de date de domenii cunoscută.",
"category_label": "Categorie",
"rule_label": "Regulă",
"list_label": "Listă",
"unknown_filter": "Filtru necunoscut {{filterId}}",
"known_tracker": "Tracker cunoscut",
"install_welcome_title": "Bun venit la AdGuard Home!",
"install_welcome_desc": "AdGuard Home este un server DNS care blochează anunțuri și trackere la nivel de rețea. Scopul său este de a vă da controlul pe întreaga rețea și toate aparatele dvs. și fără un program din partea clientului.",
"install_welcome_desc": "AdGuard Home este un server DNS care blochează reclame și trackere la nivel de rețea. Scopul său este de a vă da controlul pe întreaga rețea și toate aparatele dvs. și fără un program din partea clientului.",
"install_settings_title": "Interfață administrator web",
"install_settings_listen": "Interfață de ascultare",
"install_settings_port": "Port",
"install_settings_interface_link": "Interfața dvs. de administrare AdGuard Home va fi disponibilă pe următoarele adrese:",
"form_error_port": "Intrați un port valid",
"form_error_port": "Introduceți un port valid",
"install_settings_dns": "Server DNS",
"install_settings_dns_desc": "Va trebui să configurați aparatele sau routerul pentru a utiliza serverul DNS pe următoarele adrese:",
"install_settings_all_interfaces": "Toate interfețele",
@@ -244,8 +268,8 @@
"install_auth_username": "Nume utilizator",
"install_auth_password": "Parola",
"install_auth_confirm": "Confirmați parola",
"install_auth_username_enter": "Intrați numele de utilizator",
"install_auth_password_enter": "Intrați parola",
"install_auth_username_enter": "Introduceți nume utilizator",
"install_auth_password_enter": "Introduceți parola",
"install_step": "Etapa",
"install_devices_title": "Configurați aparatele dvs",
"install_devices_desc": "Pentru a începe să utilizați AdGuard Home, trebuie să configurați aparatele.",
@@ -256,22 +280,22 @@
"install_devices_address": "Serverul DNS AdGuard Home ascultă pe următoarele adrese",
"install_devices_router_list_1": "Deschideți preferințele pentru routerul dvs. De obicei, îl puteți accesa din browserul dvs. printr-o adresă URL (cum ar fi http://192.168.0.1/ sau http://192.168.1.1/). Vi se poate cere să introduceți parola. Dacă nu v-o amintiți, puteți reseta adesea parola apăsând un buton de pe routerul propriu-zis. Unele routere necesită o aplicație specifică, care în acest caz ar trebui să fie deja instalată pe computerul/telefonul dvs.",
"install_devices_router_list_2": "Găsiți setările DHCP/DNS. Căutați literele DNS lângă un câmp care să permită două sau trei seturi de numere, fiecare împărțit în patru grupuri de una până la trei cifre.",
"install_devices_router_list_3": "Intrați adresele serverului dvs. AdGuard Home aici.",
"install_devices_router_list_4": "Unele routere nu permit setarea unui server DNS personalizat. În acest caz, vă poate ajuta dacă configurați AdGuard Home ca server DHCP. Dacă nu, trebuie căutat manualul modelului dvs. de router ca să aflați cum se pot personaliza serverele DNS.",
"install_devices_router_list_3": "Introduceți adresele serverului dvs. AdGuard Home aici.",
"install_devices_router_list_4": "Unele routere nu permit setarea unui server DNS personalizat. În acest caz, vă poate ajuta dacă ați configura AdGuard Home ca <0>server DHCP</0>. Dacă nu, trebuie căutat manualul modelului dvs. de router ca să aflați cum se pot personaliza serverele DNS.",
"install_devices_windows_list_1": "Deschideți panoul de control prin meniul Start sau căutare Windows.",
"install_devices_windows_list_2": "Accesați categoria \"Rețea și Internet\", apoi la \"Centrul de Rețea și Partajare\".",
"install_devices_windows_list_3": "În partea stângă a ecranului găsiți \"Schimbare setări adaptor\" și faceți clic pe el.",
"install_devices_windows_list_3": "În partea stângă a ecranului găsiți \"Schimbare setări adaptor\" și clicați pe el.",
"install_devices_windows_list_4": "Selectați conexiunea activă, faceți clic dreapta pe ea și alegeți \"Proprietăți\".",
"install_devices_windows_list_5": "Găsiți Internet Protocol Versiunea 4 (TCP/IP) din listă, selectați-l și apoi faceți din nou clic pe Proprietăți.",
"install_devices_windows_list_5": "Găsiți Internet Protocol Versiunea 4 (TCP/IP) din listă, selectați-l și apoi clicați din nou pe Proprietăți.",
"install_devices_windows_list_6": "Alegeți Utilizați următoarele adrese de server DNS și introduceți adresele de server AdGuard Home.",
"install_devices_macos_list_1": "Faceți clic pe pictograma Apple și accesați Preferințele Sistemului.",
"install_devices_macos_list_2": "Faceți clic pe Network.",
"install_devices_macos_list_3": "Selectați prima conexiune din listă și faceți clic pe Avansat.",
"install_devices_macos_list_1": "Clicați pe icoana Apple și accesați Preferințele Sistemului.",
"install_devices_macos_list_2": "Clicați pe Network.",
"install_devices_macos_list_3": "Selectați prima conexiune din listă și clicați pe Avansat.",
"install_devices_macos_list_4": "Selectați fila DNS și introduceți adresele serverului dvs. AdGuard Home.",
"install_devices_android_list_1": "Din ecranul principal al Meniului Android, tapați Setări.",
"install_devices_android_list_2": "Tapați Wi-Fi din meniu. Ecranul cu toate rețelele disponibile va fi afișat (este imposibil să setați DNS personalizat pentru conexiunea mobilă).",
"install_devices_android_list_3": "Apăsați lung pe rețeaua la care sunteți conectat și tapați Modificare Rețea.",
"install_devices_android_list_4": "Pe unele aparate, poate fi necesar să bifați caseta Advanced pentru a vedea setările ulterioare. Pentru a ajusta setările DNS Android, va trebui să comutați setările IP de la DHCP la Static.",
"install_devices_android_list_4": "Pe unele aparate, poate fi necesar să bifați caseta Advanced pentru a vedea setările adiționale. Pentru a ajusta setările DNS Android, va trebui să comutați setările IP de la DHCP la Static.",
"install_devices_android_list_5": "Schimbați valorile DNS 1 și DNS 2 la cele ale serverului dvs. AdGuard Home.",
"install_devices_ios_list_1": "Din ecranul de start, tapați Setări.",
"install_devices_ios_list_2": "Alegeți Wi-Fi în meniul din stânga (este imposibil să configurați DNS pentru rețelele mobile).",
@@ -285,8 +309,8 @@
"encryption_desc": "Suport de Criptare (HTTPS/TLS) pentru DNS și interfața web administrator",
"encryption_config_saved": "Configurația de criptare salvată",
"encryption_server": "Nume de server",
"encryption_server_enter": "Intrați numele domeniului",
"encryption_server_desc": "Pentru a utiliza HTTPS, trebuie intrat numele serverului care corespunde certificatului SSL.",
"encryption_server_enter": "Introduceți numele domeniului",
"encryption_server_desc": "Pentru a utiliza HTTPS, trebuie introdus numele serverului care corespunde certificatului SSL.",
"encryption_redirect": "Redirecționați automat la HTTPS",
"encryption_redirect_desc": "Dacă este bifat, AdGuard Home vă va redirecționa automat de la adrese HTTP la HTTPS.",
"encryption_https": "Port HTTPS",
@@ -302,10 +326,10 @@
"encryption_key_input": "Copiați/lipiți cheia dvs. privată PEM-codată pentru certificatul dvs. aici.",
"encryption_enable": "Activați criptarea (HTTPS, DNS-over-HTTPS, și DNS-over-TLS)",
"encryption_enable_desc": "Dacă este activată criptarea, interfața administrator AdGuard Home va lucra peste HTTPS, și serverul DNS va asculta pentru cereri peste DNS-over-HTTPS și DNS-over-TLS.",
"encryption_chain_valid": "Lanțul de certificate valid",
"encryption_chain_invalid": "Lanțul de certificate nevalid",
"encryption_chain_valid": "Lanț de certificate valid",
"encryption_chain_invalid": "Lanț de certificate invalid",
"encryption_key_valid": "Aceasta este o cheie privată {{type}} validă",
"encryption_key_invalid": "Aceasta este o cheie privată {{type}} nevalidă",
"encryption_key_invalid": "Aceasta este o cheie privată {{type}} invalidă",
"encryption_subject": "Obiect",
"encryption_issuer": "Emitent",
"encryption_hostnames": "Nume de host",
@@ -317,7 +341,7 @@
"form_error_equal": "Nu trebuie să fie egale",
"form_error_password": "Parolele nu corespund",
"reset_settings": "Resetare setări",
"update_announcement": "AdGuard Home {{version}} este disponibil! <0>Faceți clic aici</0> pentru mai multe informații.",
"update_announcement": "AdGuard Home {{version}} este disponibil! <0>Clicați aici</0> pentru mai multe informații.",
"setup_guide": "Ghid de instalare",
"dns_addresses": "Adrese DNS",
"dns_start": "Serverul DNS demarează",
@@ -341,11 +365,12 @@
"client_identifier": "Identificator",
"ip_address": "Adresa IP",
"client_identifier_desc": "Clienții pot fi identificați prin adresa IP, CIDR, adresa MAC. Vă rugăm să rețineți că utilizarea MAC ca identificator este posibilă numai dacă AdGuard Home este și un <0>server DHCP</0>",
"form_enter_ip": "Intrați IP",
"form_enter_mac": "Intrați MAC",
"form_enter_id": "Intrați identificator",
"form_enter_ip": "Introduceți IP",
"form_enter_mac": "Introduceți MAC",
"form_enter_id": "Introduceți identificator",
"form_add_id": "Adăugați identificator",
"form_client_name": "Intrați nume client",
"form_client_name": "Introduceți nume client",
"name": "Nume",
"client_global_settings": "Folosiți setări globale",
"client_deleted": "Clientul \"{{key}}\" a fost șters cu succes",
"client_added": "Clientul \"{{key}}\" a fost adăugat cu succes",
@@ -354,7 +379,7 @@
"client_confirm_delete": "Sunteți sigur că doriți să ștergeți clientul \"{{key}}\"?",
"list_confirm_delete": "Sigur doriți să ștergeți această listă?",
"auto_clients_title": "Clienți (runtime)",
"auto_clients_desc": "Date despre clienții folosite de AdGuard Home, dar care nu sunt stocate în configurație",
"auto_clients_desc": "Date despre clienții care folosesc AdGuard Home, dar care nu sunt stocate în configurație",
"access_title": "Setări de acces",
"access_desc": "Aici puteți configura regulile de acces pentru serverul DNS AdGuard Home.",
"access_allowed_title": "Clienți autorizați",
@@ -362,20 +387,20 @@
"access_disallowed_title": "Clienți neautorizați",
"access_disallowed_desc": "O listă de adrese CIDR sau IP. Dacă este configurat, AdGuard Home va elimina cererile de la aceste adrese IP.",
"access_blocked_title": "Domenii blocate",
"access_blocked_desc": "Nu confundați acest lucru cu filtrele. AdGuard Home va bloca interogări DNS cu aceste domenii în întrebare. Aici puteți specifica exact numele de domeniu, wildcard și reguli-urlfilter, de ex. 'examplu.org', '*.examplu.org' sau '||exemplu.org^'.",
"access_blocked_desc": "Nu confundați acest lucru cu filtrele. AdGuard Home va bloca interogări DNS cu aceste domenii în întrebare. Aici puteți specifica exact numele de domeniu, wildcard și reguli-urlfilter, de ex. 'exemplu.org', '*.exemplu.org' sau '||exemplu.org^'.",
"access_settings_saved": "Setările de acces au fost salvate cu succes",
"updates_checked": "Actualizările au fost verificate cu succes",
"updates_version_equal": "AdGuard Home este la zi",
"check_updates_now": "Verificați actualizările acum",
"dns_privacy": "Confidențialitate DNS",
"setup_dns_privacy_1": "<0>DNS-over-TLS:</0> Folosiți stringul <1>{{address}}</1>.",
"setup_dns_privacy_2": "<0>DNS-over-HTTPS:</0> Utilizați stringul <1>{{address}}</1>.",
"setup_dns_privacy_3": "<0>Rețineți că protocoalele DNS criptate sunt acceptate numai pe Android 9. Așadar, trebuie să instalați software suplimentar pentru alte sisteme de operare.</0><0>Iată o listă de software pe care o puteți utiliza.</0>",
"setup_dns_privacy_android_1": "Android 9 acceptă nativ DNS-over-TLS. Pentru a o configura, accesați Setări → Rețea și internet → Advanced → Private DNS și introduceți numele de domeniu acolo.",
"setup_dns_privacy_2": "<0>DNS-over-HTTPS:</0> Folosiți stringul <1>{{address}}</1>.",
"setup_dns_privacy_3": "<0>Rețineți că protocoalele DNS criptate sunt acceptate numai pe Android 9. Așadar, trebuie să instalați programe suplimentare pentru alte sisteme de operare.</0><0>Iată o listă de software pe care o puteți utiliza.</0>",
"setup_dns_privacy_android_1": "Android 9 acceptă DNS-over-TLS nativ. Pentru a-l configura, accesați Setări → Rețea și internet → Advanced → Private DNS și introduceți numele de domeniu acolo.",
"setup_dns_privacy_android_2": "<0>AdGuard pentru Android</0> acceptă <1>DNS-over-HTTPS</1> și <1>DNS-over-TLS</1>.",
"setup_dns_privacy_android_3": "<0>Intra</0> adaugă <1>DNS-over-HTTPS</1> suport pentru Android.",
"setup_dns_privacy_ios_1": "<0>DNSCloak</0> acceptă <1>DNS-over-HTTPS</1>, dar pentru a-l configura pentru a utiliza propriul server, va trebui să generezi un <2>DNS Stamp</2> pentru aceasta.",
"setup_dns_privacy_ios_2": "<0>AdGuard pentru iOS</0> acceptă instalarea<1>DNS-over-HTTPS</1> și <1>DNS-over-TLS</1>.",
"setup_dns_privacy_ios_1": "<0>DNSCloak</0> acceptă <1>DNS-over-HTTPS</1>, dar pentru a-l configura pentru a utiliza propriul server, va trebui să generi un <2>DNS Stamp</2> pentru aceasta.",
"setup_dns_privacy_ios_2": "<0>AdGuard pentru iOS</0> acceptă instalarea <1>DNS-over-HTTPS</1> și <1>DNS-over-TLS</1>.",
"setup_dns_privacy_other_title": "Alte implementări",
"setup_dns_privacy_other_1": "AdGuard Home poate fi un client DNS sigur pe orice platformă.",
"setup_dns_privacy_other_2": "<0>dnsproxy</0> acceptă toate protocoalele DNS securizate cunoscute.",
@@ -383,7 +408,7 @@
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0> acceptă <1>DNS-over-HTTPS</1>.",
"setup_dns_privacy_other_5": "Veți găsi mai multe implementări <0>aici</0> și <1>aici</1>.",
"setup_dns_notice": "Pentru a utiliza <1>DNS-over-HTTPS</1> sau <1>DNS-over-TLS</1>, trebuie să <0>configurați Criptarea</0> în setările AdGuard Home.",
"rewrite_added": "Rescriere DNS pentru \"{{key}}\" adăugat cu succes",
"rewrite_added": "Rescriere DNS pentru \"{{key}}\" adăugată cu succes",
"rewrite_deleted": "Rescriere DNS pentru \"{{key}}\" ștearsă cu succes",
"rewrite_add": "Adăugați rescriere DNS",
"rewrite_not_found": "Nu s-au găsit rescrieri DNS",
@@ -392,13 +417,13 @@
"rewrite_applied": "Regula de rescriere s-a aplicat",
"rewrite_hosts_applied": "Rescrisă de regula fișierului hosts",
"dns_rewrites": "Rescrieri DNS",
"form_domain": "Intrați un nume de domeniu sau wildcard",
"form_answer": "Intrați adresa IP sau numele de domeniu",
"form_error_domain_format": "Format de răspuns nevalid",
"form_error_answer_format": "Format de răspuns nevalid",
"form_domain": "Introduceți un nume de domeniu sau wildcard",
"form_answer": "Introduceți adresa IP sau numele de domeniu",
"form_error_domain_format": "Format de răspuns invalid",
"form_error_answer_format": "Format de răspuns invalid",
"configure": "Configurați",
"main_settings": "Setări principale",
"block_services": "Blocare anumite servicii",
"block_services": "Blochează anumite servicii",
"blocked_services": "Servicii blocate",
"blocked_services_desc": "Permite blocarea rapidă a site-urilor și serviciilor populare.",
"blocked_services_saved": "Serviciile blocate au fost salvate cu succes",
@@ -422,11 +447,11 @@
"filter_added_successfully": "Filtrul a fost adăugat cu succes",
"filter_updated": "Filtrul a fost actualizat cu succes",
"statistics_configuration": "Configurația statisticilor",
"statistics_retention": "Statistică retenții",
"statistics_retention": "Păstrarea statisticilor",
"statistics_retention_desc": "Dacă reduceți valoarea intervalului, unele date vor fi pierdute",
"statistics_clear": " Șterge statisticile",
"statistics_clear_confirm": "Sunteți sigur că doriți să ștergeți statisticile?",
"statistics_retention_confirm": "Sunteți sigur că doriți să schimbați retenția statisticilor? Dacă reduceți valoarea intervalului, unele date vor fi pierdute",
"statistics_retention_confirm": "Sunteți sigur că doriți să schimbați păstrarea statisticilor? Dacă reduceți valoarea intervalului, unele date vor fi pierdute",
"statistics_cleared": "Statisticile au fost șterse cu succes",
"interval_hours": "{{count}} oră",
"interval_hours_plural": "{{count}} ore",
@@ -435,9 +460,9 @@
"filters_interval": "Interval de actualizare filtre",
"disabled": "Dezactivat",
"username_label": "Nume utilizator",
"username_placeholder": "Intrați numele de utilizator",
"username_placeholder": "Introduceți nume utilizator",
"password_label": "Parola",
"password_placeholder": "Intrați parola",
"password_placeholder": "Introduceți parola",
"sign_in": "Conectare",
"sign_out": "Deconectare",
"forgot_password": "Ați uitat parola?",
@@ -445,28 +470,29 @@
"location": "Locația",
"orgname": "Numele organizației",
"netname": "Numele rețelei",
"network": "Rețea",
"descr": "Descriere",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Aflați mai multe</0> despre crearea propriilor liste hosts.",
"blocked_by_response": "Blocat de CNAME sau IP ca răspuns",
"try_again": "Încercați din nou",
"domain_desc": "Intrați un nume de domeniu sau wildcard care doriți să fie rescris.",
"domain_desc": "Introduceți un nume de domeniu sau wildcard care doriți să fie rescris.",
"example_rewrite_domain": "rescrie răspunsuri numai pentru acest nume de domeniu.",
"example_rewrite_wildcard": "rescrie răspunsuri pentru toate subdomeniile <0>exemplu.org</0>.",
"disable_ipv6": "Dezactivați IPv6",
"disable_ipv6_desc": "Dacă această opțiune este activată, toate interogările DNS pentru adrese IPv6 (tip AAAA) vor fi anulate.",
"fastest_addr": "Cea mai rapidă adresă IP",
"fastest_addr_desc": "Interogați toate serverele DNS și returnați cea mai rapidă adresă IP din răspunsuri",
"autofix_warning_text": "Dacă faceți clic pe \"Fix\", AdGuardHome va configura sistemul dvs. pentru a utiliza serverul DNS AdGuardHome.",
"autofix_warning_list": "Va efectua aceste sarcini: <0>Dezactivare sistem DNSStubListener</0> <0>Setare adresă server DNS la 127.0.0.1</0> <0>Înlocuire țintei legăturii simbolice a /etc/resolv.conf pentru /run/systemd/resolve/resolv.conf</0> <0>Oprire DNSStubListener (reîncărcare servici rezolvat prin sistem)</0>",
"autofix_warning_result": "Ca urmare, toate cererile DNS de la sistemul dvs. vor fi procesate în mod implicit de AdGuardHome.",
"fastest_addr_desc": "Interogările la toate serverele DNS întorc adresa IP cea mai rapidă din răspunsuri. Așteptarea răspunsului tuturor serverelor DNS face interogările DNS mai lente dar se ameliorează conectivitatea generală.",
"autofix_warning_text": "Dacă clicați pe \"Fix\", AdGuardHome va configura sistemul dvs. pentru a utiliza serverul DNS AdGuardHome.",
"autofix_warning_list": "Va efectua aceste sarcini: <0>Dezactivare sistem DNSStubListener</0> <0>Setare adresă server DNS la 127.0.0.1</0> <0>Înlocuire link simbolic țintă /etc/resolv.conf cu /run/systemd/resolve/resolv.conf</0> <0>Oprire DNSStubListener (reîncărcare servici rezolvat prin sistem)</0>",
"autofix_warning_result": "Ca urmare, toate cererile DNS ale sistemul dvs. vor fi procesate în mod implicit de AdGuardHome.",
"tags_title": "Etichete",
"tags_desc": "Puteți selecta etichetele care corespund clientului. Etichetele pot fi incluse în regulile de filtrare și vă permit să le aplicați mai exact. <0>Aflați mai multe</0>",
"form_select_tags": "Selectați etichete client",
"check_title": "Verificați filtrarea",
"check_desc": "Verificați dacă numele de host este filtrat",
"check": "Verificați",
"form_enter_host": "Intrați un nume de host",
"form_enter_host": "Introduceți un nume de host",
"filtered_custom_rules": "Filtrat prin reguli de filtrare personalizate",
"host_whitelisted": "Numele de host este în lista albă",
"check_ip": "Adrese IP: {{ip}}",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} listă actualizată",
"list_updated_plural": "{{count}} liste actualizate",
"dnssec_enable": "Activați DNSSEC",
"dnssec_enable_desc": "Setați steagul DNSSEC pe interogările DNS de ieșire și verificați rezultatul (este necesar un resolver DNSSEC activat)"
"dnssec_enable_desc": "Setați steagul DNSSEC pe interogările DNS de ieșire și verificați rezultatul (este necesar un resolver DNSSEC activat)",
"validated_with_dnssec": "Validat cu DNSSEC",
"show_all_responses": "Toate răspunsurile",
"show_blocked_responses": "Blocat",
"show_whitelisted_responses": "Pe lista albă",
"show_processed_responses": "Tratat",
"blocked_safebrowsing": "Blocat de Navigarea securitară",
"blocked_adult_websites": "Site-uri pentru adulți blocate",
"blocked_threats": "Amenințări blocate",
"allowed": "Permise",
"filtered": "Filtrate",
"rewritten": "Rescrise",
"safe_search": "Căutare sigură",
"blocklist": "Lista neagră",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Вы можете указать DNS-сервер <0>для конкретного домена(-ов)</0>",
"upstream_parallel": "Использовать параллельные запросы ко всем серверам одновременно для ускорения обработки запроса",
"parallel_requests": "Параллельные запросы",
"load_balancing": "Распределение нагрузки\n",
"load_balancing_desc": "Запрашивайте по одному серверу за раз. AdGuard Home будет использовать случайный алгоритм для выбора сервера, так что самый быстрый сервер будет использоваться чаще.",
"bootstrap_dns": "Bootstrap DNS-серверы",
"bootstrap_dns_desc": "Bootstrap DNS-серверы используются для поиска IP-адресов DoH/DoT серверов, которые вы указали.",
"check_dhcp_servers": "Проверить DHCP-серверы",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Выбрать интерфейс DHCP",
"dhcp_hardware_address": "Аппаратный адрес",
"dhcp_ip_addresses": "IP-адреса",
"ip": "IP-адрес",
"dhcp_table_hostname": "Имя хоста",
"dhcp_table_expires": "Истекает",
"dhcp_warning": "Если вы все равно хотите включить DHCP-сервер, убедитесь, что в сети больше нет активных DHCP-серверов. Иначе это может сломать доступ в сеть для подключенных устройств!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "Не найдено статических аренд DHCP",
"dhcp_add_static_lease": "Добавить статическую аренду",
"dhcp_reset": "Вы уверены, что хотите сбросить настройки DHCP?",
"country": "Страна",
"city": "Город",
"delete_confirm": "Are you sure you want to delete \"{{key}}\"?",
"form_enter_hostname": "Введите имя хоста",
"error_details": "Детализация ошибки",
"response_details": "Детали ответа",
"request_details": "Детали запроса",
"client_details": "Информация о клиенте",
"details": "Детали",
"back": "Назад",
"dashboard": "Панель управления",
"settings": "Настройки",
"filters": "Фильтры",
"filter": "Фильтр",
"query_log": "Журнал",
"compact": "Компактный",
"nothing_found": "Ничего не найдено",
"faq": "FAQ",
"version": "версия",
"address": "адрес",
"address": "Адрес",
"protocol": "Протокол",
"on": "Вкл",
"off": "Выкл",
"copyright": "Все права защищены",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Количество правил:",
"last_time_updated_table_header": "Последнее обновление",
"actions_table_header": "Действия",
"request_table_header": "Запрос",
"edit_table_action": "Редактировать",
"delete_table_action": "Удалить",
"elapsed": "Затрачено",
"filters_and_hosts_hint": "AdGuard Home распознает базовые правила блокировки и синтаксис файлов hosts.",
"no_blocklist_added": "Черные списки не добавлены",
"no_whitelist_added": "Белые списки не добавлены",
@@ -162,20 +177,23 @@
"example_comment_hash": "# И вот так тоже",
"example_regex_meaning": "блокирует доступ к доменам, соответствующим <0>заданному регулярному выражению</0>",
"example_upstream_regular": "обычный DNS (поверх UDP)",
"example_upstream_dot": "зашифрованный <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-поверх-TLS</a>",
"example_upstream_doh": "зашифрованный <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "вы можете использовать <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> для <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> или <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> резолверов",
"example_upstream_dot": "зашифрованный <0>DNS-over-TLS</0>",
"example_upstream_doh": "зашифрованный <0>DNS-over-HTTPS</0>",
"example_upstream_sdns": "вы можете использовать <0>DNS Stamps</0> для <1>DNSCrypt</1> или <2>DNS-over-HTTPS</2> резолверов",
"example_upstream_tcp": "обычный DNS (поверх TCP)",
"all_lists_up_to_date_toast": "Все списки уже обновлены",
"updated_upstream_dns_toast": "Upstream DNS-серверы обновлены",
"dns_test_ok_toast": "Указанные серверы DNS работают корректно",
"dns_test_not_ok_toast": "Сервер \"{{key}}\": невозможно использовать, проверьте правильность написания",
"unblock_btn": "Разблокировать",
"block_btn": "Заблокировать",
"unblock": "Разблокировать",
"block": "Заблокировать",
"time_table_header": "Время",
"date": "Дата",
"domain_name_table_header": "Домен",
"domain_or_client": "Домен или клиент",
"type_table_header": "Тип",
"response_table_header": "Ответ",
"response_code": "Код ответа",
"client_table_header": "Клиент",
"empty_response_status": "Пусто",
"show_all_filter_type": "Показать все",
@@ -194,6 +212,7 @@
"query_log_filtered": "Отфильтровано с помощью {{filter}}",
"query_log_confirm_clear": "Вы уверены, что хотите очистить весь журнал запросов?",
"query_log_cleared": "Журнал запросов успешно очищен",
"query_log_updated": "Журнал запросов успешно обновлен",
"query_log_clear": "Очистить журнал запросов",
"query_log_retention": "Сохранение журнала запросов",
"query_log_enable": "Включить журнал",
@@ -211,6 +230,9 @@
"custom_ip": "Свой IP",
"blocking_ipv4": "Блокировка IPv4",
"blocking_ipv6": "Блокировка IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "Нешифрованный DNS",
"form_enter_rate_limit": "Введите rate limit",
"rate_limit": "Rate limit",
"edns_enable": "Включить отправку EDNS Client Subnet",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Нулевой IP: Отвечает с нулевым IP-адресом (0.0.0.0 для A; :: для AAAA)",
"blocking_mode_custom_ip": "Пользовательский IP: Отвечает с вручную настроенным IP-адресом",
"upstream_dns_client_desc": "Если оставить поле пустым, AdGuard Home будет обращаться к серверам, указанным в <0>настройках DNS</0>.",
"tracker_source": "Источник трекинга",
"source_label": "Источник",
"found_in_known_domain_db": "Найден в базе известных доменов.",
"category_label": "Категория",
"rule_label": "Правило",
"list_label": "Список",
"unknown_filter": "Неизвестный фильтр {{filterId}}",
"known_tracker": "Известный трекер",
"install_welcome_title": "Добро пожаловать в AdGuard Home!",
"install_welcome_desc": "AdGuard Home это DNS-сервер, блокирующий рекламу и трекинг. Его цель дать вам возможность контролировать всю вашу сеть и все подключенные устройства. Он не требует установки клиентских программ.",
"install_settings_title": "Веб-интерфейс администрирования",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "Откройте настройки вашего роутера. Обычно вы можете открыть их в вашем браузере (например, http://192.168.0.1/ или http://192.168.1.1/). Вас могут попросить ввести пароль. Если вы не помните его, пароль часто можно сбросить, нажав на кнопку на самом роутере. Некоторые роутеры требуют специального приложения, которое в этом случае должно быть уже установлено на ваш компьютер или телефон.",
"install_devices_router_list_2": "Найдите настройки DHCP или DNS. Найдите буквы \"DNS\" рядом с текстовым полем, в которое можно ввести два или три ряда цифр, разделенных на 4 группы от одной до трёх цифр.",
"install_devices_router_list_3": "Введите туда адрес вашего AdGuard Home.",
"install_devices_router_list_4": "Вы не можете установить собственный DNS-сервер на некоторых типах маршрутизаторов. В этом случае может помочь настройка AdGuard Home в качестве DHCP-сервера. В противном случае вам следует обратиться к руководству по настройке DNS-серверов для вашей конкретной модели маршрутизатора.",
"install_devices_router_list_4": "Вы не можете установить собственный DNS-сервер на некоторых типах маршрутизаторов. В этом случае может помочь настройка AdGuard Home в качестве <0>DHCP-сервера</0>. В противном случае вам следует обратиться к руководству по настройке DNS-серверов для вашей конкретной модели маршрутизатора.",
"install_devices_windows_list_1": "Откройте Панель управления через меню \"Пуск\" или через поиск Windows.",
"install_devices_windows_list_2": "Перейдите в \"Сеть и интернет\", а затем в \"Центр управления сетями и общим доступом\"",
"install_devices_windows_list_3": "В левой стороне экрана найдите \"Изменение параметров адаптера\" и кликните по нему.",
@@ -346,6 +370,7 @@
"form_enter_id": "Введите идентификатор",
"form_add_id": "Добавить идентификатор",
"form_client_name": "Введите имя клиента",
"name": "Имя",
"client_global_settings": "Использовать глобальные настройки",
"client_deleted": "Клиент \"{{key}}\" успешно удален",
"client_added": "Клиент \"{{key}}\" успешно добавлен",
@@ -445,6 +470,7 @@
"location": "Местоположение",
"orgname": "Название организации",
"netname": "Название сети",
"network": "Сеть",
"descr": "Описание",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Узнайте больше</0> о создании собственных списков блокировки хостов.",
@@ -489,5 +515,19 @@
"list_updated": "Обновлен {{count}} список",
"list_updated_plural": "Обновлено списков: {{count}}",
"dnssec_enable": "Включить DNSSEC",
"dnssec_enable_desc": "Установите флаг DNSSEC в исходящих DNS-запросах и проверьте результат (требуется резолвер с поддержкой DNSSEC)"
}
"dnssec_enable_desc": "Установите флаг DNSSEC в исходящих DNS-запросах и проверьте результат (требуется резолвер с поддержкой DNSSEC)",
"validated_with_dnssec": "Подтверждено с помощью DNSSEC",
"show_all_responses": "Все ответы",
"show_blocked_responses": "Blocked",
"show_whitelisted_responses": "В белом списке",
"show_processed_responses": "Обработан",
"blocked_safebrowsing": "Заблокировано согласно базе данных Safebrowsing",
"blocked_adult_websites": "Заблокированные \"взрослые\" сайты",
"blocked_threats": "Заблокировано угроз",
"allowed": "Разрешенные",
"filtered": "Отфильтрованные",
"rewritten": "Переписанные",
"safe_search": "Безопасный поиск",
"blocklist": "Черный список",
"milliseconds_abbreviation": "мс"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "Môžete zadať DNS upstream <0>pre konkrétnu doménu (domény)</0>",
"upstream_parallel": "Používať paralelné dopyty na zrýchlenie súčasným dopytovaním všetkých serverov",
"parallel_requests": "Paralelné dopyty",
"load_balancing": "Vyrovnávanie záťaže",
"load_balancing_desc": "Dopytujte jeden server súčasne. AdGuard Home použije na výber servera vážený náhodný algoritmus, aby sa najrýchlejší server používal častejšie.",
"bootstrap_dns": "Bootstrap DNS servery",
"bootstrap_dns_desc": "Bootstrap DNS servery sa používajú na rozlíšenie IP adries DoH/DoT rezolverov, ktoré zadáte ako upstreams.",
"check_dhcp_servers": "Skontrolovať DHCP servery",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Zvoľte DHCP rozhranie",
"dhcp_hardware_address": "Hardware adresa",
"dhcp_ip_addresses": "IP adresy",
"ip": "IP",
"dhcp_table_hostname": "Meno hostiteľa",
"dhcp_table_expires": "Vyprší",
"dhcp_warning": "Ak chcete server DHCP napriek tomu povoliť, uistite sa, že v sieti nie je žiadny iný aktívny DHCP server. V opačnom prípade sa môže prerušiť internet pre už pripojené zariadenia!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "Nebol nájdený žiadny statický DHCP prenájom",
"dhcp_add_static_lease": "Pridať statický prenájom",
"dhcp_reset": "Naozaj chcete obnoviť konfiguráciu DHCP?",
"country": "Krajina",
"city": "Mesto",
"delete_confirm": "Naozaj chcete vymazať \"{{key}}\"?",
"form_enter_hostname": "Zadajte meno hostiteľa",
"error_details": "Podrobnosti chyby",
"response_details": "Podrobnosti odpovede",
"request_details": "Podrobnosti požiadavky",
"client_details": "Podrobnosti klienta",
"details": "Podrobnosti",
"back": "Naspäť",
"dashboard": "Riadiaci panel",
"settings": "Nastavenia",
"filters": "Filtre",
"filter": "Filter",
"query_log": "Denník dopytov",
"compact": "Kompaktný",
"nothing_found": "Nič sa nenašlo",
"faq": "FAQ",
"version": "Verzia",
"address": "adresa",
"address": "Adresa",
"protocol": "Protokol",
"on": "ZAP.",
"off": "VYP.",
"copyright": "Copyright",
@@ -132,8 +145,10 @@
"rules_count_table_header": "Počet pravidiel",
"last_time_updated_table_header": "Posledná aktualizácia",
"actions_table_header": "Akcie",
"request_table_header": "Dopyt",
"edit_table_action": "Upraviť",
"delete_table_action": "Vymazať",
"elapsed": "Uplynuté",
"filters_and_hosts_hint": "AdGuard Home pozná základné pravidlá adblock a syntax hosts súborov.",
"no_blocklist_added": "Nebol pridaný žiaden zoznam blokovaných DNS",
"no_whitelist_added": "Nebol pridaný žiaden zoznam povolených DNS",
@@ -170,12 +185,15 @@
"updated_upstream_dns_toast": "Aktualizované upstream DNS servery",
"dns_test_ok_toast": "Špecifikované DNS servery pracujú korektne",
"dns_test_not_ok_toast": "Server \"{{key}}\": nemohol byť použitý, skontrolujte, či ste ho správne napísali",
"unblock_btn": "Odblokovať",
"block_btn": "Zablokovať",
"unblock": "Odblokovať",
"block": "Blokovať",
"time_table_header": "Čas",
"date": "Dátum",
"domain_name_table_header": "Meno domény",
"domain_or_client": "Doména alebo klient",
"type_table_header": "Typ",
"response_table_header": "Odozva",
"response_code": "Kód odozvy",
"client_table_header": "Klient",
"empty_response_status": "Vyčistiť",
"show_all_filter_type": "Zobraziť všetko",
@@ -194,6 +212,7 @@
"query_log_filtered": "Vyfiltrované pomocou {{filter}}",
"query_log_confirm_clear": "Naozaj chcete vymazať celý denník dopytov?",
"query_log_cleared": "Denník dopytov bol úspešne vymazaný",
"query_log_updated": "Denník dopytov bol úspešne aktualizovaný",
"query_log_clear": "Vymazať denníky dopytov",
"query_log_retention": "Obdobie záznamu denníka dopytov",
"query_log_enable": "Zapnúť denník",
@@ -211,6 +230,9 @@
"custom_ip": "Vlastná IP adresa",
"blocking_ipv4": "Blokovanie IPv4",
"blocking_ipv6": "Blokovanie IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "Obyčajné DNS",
"form_enter_rate_limit": "Zadajte rýchlostný limit",
"rate_limit": "Rýchlostný limit",
"edns_enable": "Povoliť klientsku podsiete EDNS",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "Null IP: Odpoveď s nulovou IP adresou (0.0.0.0 pre A; :: pre AAAA)",
"blocking_mode_custom_ip": "Vlastná IP adresa: Odpovedzte s manuálne nastavenou IP adresou",
"upstream_dns_client_desc": "Ak ponecháte toto pole prázdne, AdGuard Home použije servery nakonfigurované v <0>nastaveniach DNS</0>.",
"tracker_source": "Zdroj sledovania",
"source_label": "Zdroj",
"found_in_known_domain_db": "Nájdené v databáze známych domén.",
"category_label": "Kategória",
"rule_label": "Pravidlo",
"list_label": "Zoznam",
"unknown_filter": "Neznámy filter {{filterId}}",
"known_tracker": "Známy sledovač",
"install_welcome_title": "Vitajte na stránkach AdGuard Home!",
"install_welcome_desc": "Doména AdGuard Home je celosieťový DNS server pre blokovanie reklám a sledovačov. Jeho cieľom je, aby ste ovládali celú Vašu sieť a všetky Vaše zariadenia, pričom sa nevyžaduje použitie akéhokoľvek programu na strane klienta.",
"install_settings_title": "Administrátorské webové rozhranie",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "Otvorte predvoľby Vášho smerovača. Zvyčajne ho môžete získať z prehliadača prostredníctvom adresy URL (napríklad http://192.168.0.1/ alebo http://192.168.1.1/). Možno bude potrebné zadať heslo. Ak si to nepamätáte, heslo môžete často obnoviť stlačením tlačidla na samotnom smerovači. Niektoré smerovače vyžadujú konkrétnu aplikáciu, ktorá by v takom prípade mala byť už nainštalovaná na Vašom počítači alebo telefóne.",
"install_devices_router_list_2": "Nájdite nastavenia DHCP/DNS. Hľadajte skratku DNS vedľa poľa, ktoré umožňuje vložiť dve alebo tri sady čísel, každé rozdelené do štyroch skupín s jedným až tromi číslicami.",
"install_devices_router_list_3": "Zadajte tam adresy Vášho AdGuard Home servera.",
"install_devices_router_list_4": "Na niektorých typoch smerovačov nemôžete nastaviť vlastný DNS server. V takom prípade môže pomôcť, ak nastavíte AdGuard Home ako DHCP server. V opačnom prípade by ste mali vyhľadať príručku, ako prispôsobiť DNS servery konkrétnemu modelu smerovača.",
"install_devices_router_list_4": "Na niektorých typoch smerovačov nemôžete nastaviť vlastný DNS server. V takom prípade môže pomôcť, ak nastavíte domovskú stránku AdGuard ako <0>DHCP server</0>. V opačnom prípade by ste mali vyhľadať príručku, ako prispôsobiť servery DNS konkrétnemu modelu smerovača.",
"install_devices_windows_list_1": "Otvorte panel Nastavenia cez menu Štart alebo vyhľadávanie Windows.",
"install_devices_windows_list_2": "Prejdite do kategórie Sieť a internet a potom do Centra sietí a zdieľania.",
"install_devices_windows_list_3": "Vyhľadajte položku Zmeniť možnosti adaptéra a kliknite na ňu",
@@ -346,6 +370,7 @@
"form_enter_id": "Zadajte identifikátor",
"form_add_id": "Pridajte identifikátor",
"form_client_name": "Zadajte meno klienta",
"name": "Meno",
"client_global_settings": "Použiť globálne nastavenia",
"client_deleted": "\"{{key}}\" klienta bol úspešne vymazaný",
"client_added": "\"{{key}}\" klienta bol úspešne pridaný",
@@ -445,6 +470,7 @@
"location": "Poloha",
"orgname": "Meno organizácie",
"netname": "Meno siete",
"network": "Sieť",
"descr": "Popis",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Dozvedieť sa viac</0> o tvorbe vlastných zoznamov hostiteľov.",
@@ -456,7 +482,7 @@
"disable_ipv6": "Vypnúť IPv6",
"disable_ipv6_desc": "Ak je táto funkcia zapnutá, všetky dotazy DNS na adresy IPv6 (typ AAAA) budú zrušené.",
"fastest_addr": "Najrýchlejšia IP adresa",
"fastest_addr_desc": "Dopytovať všetky DNS servery a vrátiť najrýchlejšiu IP adresu zo všetkých odpovedí",
"fastest_addr_desc": "Dopytovať všetky servery DNS a vrátiť najrýchlejšiu IP adresu zo všetkých odpovedí. Toto spomalí dotazy DNS, pretože musíme čakať na odpovede zo všetkých serverov DNS, ale zlepší sa celkové pripojenie.",
"autofix_warning_text": "Ak kliknete na „Opraviť“, AdGuardHome nakonfiguruje Váš systém tak, aby používal DNS server AdGuardHome.",
"autofix_warning_list": "Bude vykonávať tieto úlohy: <0>Deaktivovať systém DNSStubListener</0> <0>Nastaviť adresu servera DNS na 127.0.0.1</0> <0>Nahradiť cieľový symbolický odkaz /etc/resolv.conf na /run/systemd/resolve/resolv.conf</0> <0>Zastaviť službu DNSStubListener (znova načítať službu systemd-resolved)</0>",
"autofix_warning_result": "Výsledkom bude, že všetky DNS dopyty z Vášho systému budú štandardne spracované službou AdGuard Home.",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} zoznam aktualizovaný",
"list_updated_plural": "{{count}} zoznamov aktualizovaných",
"dnssec_enable": "Zapnúť DNSSEC",
"dnssec_enable_desc": "Nastavte príznak DNSSEC v nasledujúcich DNS dopytoch a skontrolujte výsledok (je potrebný prekladač so zapnutým DNSSEC)"
"dnssec_enable_desc": "Nastavte príznak DNSSEC v nasledujúcich DNS dopytoch a skontrolujte výsledok (je potrebný prekladač so zapnutým DNSSEC)",
"validated_with_dnssec": "Overené pomocou DNSSEC",
"show_all_responses": "Všetky odpovede",
"show_blocked_responses": "Zablokované",
"show_whitelisted_responses": "Obsiahnuté v bielej listine",
"show_processed_responses": "Spracované",
"blocked_safebrowsing": "Zablokované modulom Bezpečné prehliadanie",
"blocked_adult_websites": "Zablokovaná stránka pre dospelých",
"blocked_threats": "Zablokované hrozby",
"allowed": "Povolené",
"filtered": "Filtrované",
"rewritten": "Prepísané",
"safe_search": "Bezpečné vyhľadávanie",
"blocklist": "Zoznam blokovaní",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "lahko določite nazgornji DNS <0>za določene domene</0>",
"upstream_parallel": "Uporabite vzporedne zahteve za pospešitev reševanja s hkratnim poizvedovanjem vseh gorvodnih strežnikov",
"parallel_requests": "Vzporedne zahteve",
"load_balancing": "Uravnavanje obremenitve",
"load_balancing_desc": "Poizvedujte po en strežnik. AdGuard Home bo uporabil uteženi naključni algoritem za izbiro strežnika, tako da bo najhitrejši strežnik uporabljen pogosteje.",
"bootstrap_dns": "Zagonski DNS strežniki",
"bootstrap_dns_desc": "Zagonski DNS strežniki se uporabljajo za razreševanje IP naslovov DoH/DoT reševalcev, ki jih določite kot navzgornje.",
"check_dhcp_servers": "Preveri strežnike DHCP",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "Izberite DHCP vmesnik",
"dhcp_hardware_address": "Naslov strojne opreme",
"dhcp_ip_addresses": "IP naslovi",
"ip": "IP",
"dhcp_table_hostname": "Ime gostitelja",
"dhcp_table_expires": "Poteče",
"dhcp_warning": "Če želite omogočiti DHCP strežnik, prepričajte se, da v vašem omrežju ni drugega aktivnega strežnika DHCP. V nasprotnem primeru lahko ta prekine internet za povezane naprave!",
@@ -49,17 +52,25 @@
"dhcp_static_leases_not_found": "Ni najdenih statičnih najemov DHCP",
"dhcp_add_static_lease": "Dodaj statičen najem",
"dhcp_reset": "Ali ste prepričani, da želite ponastaviti konfiguracijo DHCP?",
"country": "Dežela",
"city": "Mesto",
"delete_confirm": "Ali ste prepričani, da želite izbrisati \"{{key}}\"?",
"form_enter_hostname": "Vnesite ime gostitelja",
"error_details": "Podrobnosti o napaki",
"response_details": "Podrobnosti o odzivu",
"request_details": "Podrobnosti o zahtevi",
"client_details": "Podatki o odjemalcu",
"details": "Podrobnosti",
"back": "Nazaj",
"dashboard": "Nadzorna plošča",
"settings": "Nastavitve",
"filters": "Filtri",
"filter": "Filtriraj",
"query_log": "Dnevnik poizvedb",
"faq": "Pogosta vprašanja in odgovori (FAQ)",
"version": "različica",
"address": "naslov",
"address": "Naslov",
"protocol": "Protokol",
"on": "VKL",
"off": "IZK",
"copyright": "Avtorske pravice",
@@ -132,8 +143,10 @@
"rules_count_table_header": "Število pravil",
"last_time_updated_table_header": "Zadnjič posodobljeno",
"actions_table_header": "Akcij",
"request_table_header": "Zahteva",
"edit_table_action": "Uredi",
"delete_table_action": "Izbriši",
"elapsed": "Potekla",
"filters_and_hosts_hint": "AdGuard Home razume osnovna pravila zaviranja oglasov in sintakso datotek gostiteljev.",
"no_blocklist_added": "Ni dodanih nobenih seznamov nedovoljenih",
"no_whitelist_added": "Ni dodanih nobenih dovoljenih seznamov",
@@ -170,10 +183,12 @@
"updated_upstream_dns_toast": "Posodobljeni Zagonske strežnike DNS",
"dns_test_ok_toast": "Navedeni strežniki DNS delujejo pravilno",
"dns_test_not_ok_toast": "Ni mogoče uporabiti: strežnika \"{{key}}\". Preverite, ali ste ga pravilno napisali",
"unblock_btn": "Omogoči",
"block_btn": "Onemogoči",
"unblock": "Omogoči",
"block": "Onemogoči",
"time_table_header": "Čas",
"date": "Datum",
"domain_name_table_header": "Ime domene",
"domain_or_client": "Domena ali odjemalec",
"type_table_header": "Vrsta",
"response_table_header": "Odgovor",
"client_table_header": "Odjemalec",
@@ -211,6 +226,9 @@
"custom_ip": "IP po meri",
"blocking_ipv4": "Onemogočanje IPv4",
"blocking_ipv6": "Onemogočanje IPv6",
"dns_over_https": "DNS-prek-HTTPS",
"dns_over_tls": "DNS-prek-TLS",
"plain_dns": "Navadni DNS",
"form_enter_rate_limit": "Vnesite omejitev hitrosti",
"rate_limit": "Omejitev hitrosti",
"edns_enable": "Omogoči podmrežje odjemalcev EDNS",
@@ -229,6 +247,7 @@
"rule_label": "Pravilo",
"list_label": "Seznam",
"unknown_filter": "Neznan filter {{filterId}}",
"known_tracker": "Znan sledilec",
"install_welcome_title": "Dobrodošli v AdGuard Home!",
"install_welcome_desc": "AdGuard Home je omrežni strežnik DNS, ki zavira oglase in sledilce v celotnem omrežju. Njegov namen je omogočanje nadzora nad celotnim omrežjem in vsemi vašimi napravami in ne zahteva uporabo odjemalskega programa.",
"install_settings_title": "Skrbniški spletni vmesnik",
@@ -257,7 +276,7 @@
"install_devices_router_list_1": "Odprite nastavitve usmerjevalnika. Ponavadi lahko do nje dostopate iz brskalnika prek URL-ja (npr. http://192.168.0.1/ ali http://192.168.1.1/). Morda boste morali vnesti geslo. Če se ne spomnite gesla, lahko pogosto ponastavite geslo s pritiskom na gumb na samem usmerjevalniku. Nekateri usmerjevalniki zahtevajo posebno aplikacijo, ki bi morala biti v tem primeru že nameščena na vašem računalniku/telefonu.",
"install_devices_router_list_2": "Poiščite nastavitve DHCP/DNS. Poiščite črke DNS poleg polja, ki dovoljuje dva ali tri naborov številk, pri čemer je vsaka razdeljena na štiri skupine z enim do tremi števili.",
"install_devices_router_list_3": "Tam vnesite svoje naslove strežnikov AdGuard Home.",
"install_devices_router_list_4": "Na nekaterih usmerjevalnikih ne morete nastaviti strežnika DNS po meri. V tem primeru bo morda pomagalo, če boste AdGuard Home postavili kot strežnik DHCP. V nasprotnem primeru poiščite priročnik, kako prilagoditi strežnike DNS za vaš določen model usmerjevalnika.",
"install_devices_router_list_4": "Na nekaterih vrstah usmerjevalnikov ne morete nastaviti strežnika DNS po meri. V tem primeru bo morda pomagalo, če boste AdGuard Home postavili kot <0>strežnik DHCP</0>. V nasprotnem primeru poiščite priročnik, kako prilagoditi strežnike DNS za vaš določen model usmerjevalnika.",
"install_devices_windows_list_1": "Odprite 'Nadzorno ploščo' prek menija 'Začetek' ali 'Iskanja v sistemu Windows'.",
"install_devices_windows_list_2": "Pojdite v 'Omrežje' in 'Kategorija interneta' in nato v 'Omrežje' in 'Središče za skupno rabo'.",
"install_devices_windows_list_3": "Na levi strani zaslona poiščite 'Spremeni nastavitve kartice' in kliknite nanjo.",
@@ -346,6 +365,7 @@
"form_enter_id": "Vnesi identifikatorja",
"form_add_id": "Dodaj identifikatorja",
"form_client_name": "Vnesite ime odjemalca",
"name": "Ime",
"client_global_settings": "Uporabi splošne nastavitve",
"client_deleted": "Odjemalec \"{{key}}\" je bil uspešno izbrisan",
"client_added": "Odjemalec \"{{key}}\" je bil uspešno dodan",
@@ -381,7 +401,7 @@
"setup_dns_privacy_other_2": "<0>dnsproxy</0> podpira vse znane varne protokole DNS.",
"setup_dns_privacy_other_3": "<0>dnscrypt-proxy</0> podpira <1>DNS-prek-HTTPS</1>.",
"setup_dns_privacy_other_4": "<0>Mozilla Firefox</0> podpira <1>DNS-prek-HTTPS</1>.",
"setup_dns_privacy_other_5": "Več izvedb boste najdli <0>tukaj</0> in <1>tukaj</1>.",
"setup_dns_privacy_other_5": "Našli boste več izvedb <0>tukaj</0> in <1>tukaj</1>.",
"setup_dns_notice": "Za uporabo <1>DNS-prek-HTTPS</1> ali <1>DNS-prek-TLS</1>, morate <0>konfigurirati šifriranje</0> v nastavitvah AdGuard Home.",
"rewrite_added": "Uspešno je dodano DNS prepisovanje za \"{{key}}\"",
"rewrite_deleted": "Uspešno je izbrisano DNS prepisovanje za \"{{key}}\"",
@@ -445,6 +465,7 @@
"location": "Lokacija",
"orgname": "Ime organizacije",
"netname": "Ime omrežja",
"network": "Omrežje",
"descr": "Opis",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Več o</0> ustvarjanju lastnih seznamov gostiteljev.",
@@ -456,7 +477,7 @@
"disable_ipv6": "Onemogoči IPv6",
"disable_ipv6_desc": "Če je ta funkcija omogočena, bodo vse poizvedbe DNS za naslove IPv6 (vrste AAAA) izpadle.",
"fastest_addr": "Najhitrejši IP naslov",
"fastest_addr_desc": "Poišči vse strežnike DNS in vrni najhitrejši IP naslov med vsemi odgovori",
"fastest_addr_desc": "Poizve vse strežnike DNS in vrne najhitrejši IP naslov med vsemi odgovori. To bo upočasnilo poizvedbe DNS, saj moramo čakati na odgovore vseh DNS strežnikov, vendar bo izboljšalo splošno povezljivost.",
"autofix_warning_text": "Če kliknete 'Popravi', bo AdGuardHome konfiguriral vaš sistem za uporabo strežnika AdGuardHome DNS.",
"autofix_warning_list": "To bo izvedlo naslednja opravila: <0>Deaktiviraj sistemski DNSStubListener</0> <0>Nastavi naslov strežnika DNS na 127.0.0.1</0> <0>Zamenjaj cilj simbolične povezave /etc/resolv.conf with /run/systemd/resolve/resolv.conf</0> <0>Zaustavi DNSStubListener (znova naloži storitev systemd-resolved)",
"autofix_warning_result": "Kot rezultat, bo vse zahteve DNS iz vašega sistema privzeto obdelal AdGuard Home.",
@@ -489,5 +510,19 @@
"list_updated": "{{count}} posodobljen seznam",
"list_updated_plural": "{{count}} posodobljenih seznamov",
"dnssec_enable": "Omogoči DNSSEC",
"dnssec_enable_desc": "V odhodnih poizvedbah DNS nastavite zastavico DNSSEC in preverite rezultat (zahtevan je omogočen reševalnik DNSSEC)"
"dnssec_enable_desc": "V odhodnih poizvedbah DNS nastavite zastavico DNSSEC in preverite rezultat (zahtevan je omogočen reševalnik DNSSEC)",
"validated_with_dnssec": "Potrjen z DNSSEC",
"show_all_responses": "Vsi odgovori",
"show_blocked_responses": "Onemogočen",
"show_whitelisted_responses": "Na seznamu dovoljenih",
"show_processed_responses": "Obdelan",
"blocked_safebrowsing": "Onemogočeno z 'Varnim brskanjem'",
"blocked_adult_websites": "Onemogočeno spletnih strani za odrasle",
"blocked_threats": "Onemogočeno groženj",
"allowed": "Dovoljeno",
"filtered": "Filtrirano",
"rewritten": "Znova napisano",
"safe_search": "Varno iskanje",
"blocklist": "Seznam nedovoljenih",
"milliseconds_abbreviation": "ms"
}

View File

@@ -2,6 +2,9 @@
"client_settings": "Postavke klijenta",
"example_upstream_reserved": "možete odrediti DNS upstream <0>za određene domene</0>",
"upstream_parallel": "Koristite paralelne zahteve da ubrzate rešavanje istovremenim zahtevanjem svih servera",
"parallel_requests": "Paralelni zahtevi",
"load_balancing": "Load-balancing",
"load_balancing_desc": "Koristi jedan server. AdGuard Home će koristiti najnoviji nasumični algoritam da izabere server tako da će najbrži server biti češće korišćen.",
"bootstrap_dns": "Bootstrap DNS serveri",
"bootstrap_dns_desc": "Bootstrap DNS serveri se koriste da reše IP adrese od DoH/DoT razrešivača koje ste odredili kao upstream.",
"check_dhcp_servers": "Proveri DHCP servere",
@@ -36,6 +39,7 @@
"dhcp_interface_select": "Izaberite DHCP okruženje",
"dhcp_hardware_address": "Adresa hardvera",
"dhcp_ip_addresses": "IP adrese",
"ip": "IP",
"dhcp_table_hostname": "Ime hosta",
"dhcp_table_expires": "Ističe",
"dhcp_warning": "Ako svakako želite da uključite DHCP server, uverite se da nema drugih aktivnih DHCP servera u vašoj mreži. U suprotnom, to može pokvariti Internet za povezane uređaje!",
@@ -48,17 +52,27 @@
"dhcp_static_leases_not_found": "Nisu pronađena statička DHCP iznajmljivanja",
"dhcp_add_static_lease": "Dodaj statičko iznajmljivanje",
"dhcp_reset": "Jeste li sigurni da želite da resetujete DHCP konfiguraciju?",
"country": "Zemlja",
"city": "Grad",
"delete_confirm": "Jeste li sigurni da želite da izbrišete \"{{key}}\"?",
"form_enter_hostname": "Unesite ime hosta",
"error_details": "Detalji greške",
"response_details": "Pojedinosti odgovora",
"request_details": "Pojedinosti zahteva",
"client_details": "Pojedinosti klijenta",
"details": "Detalji",
"back": "Nazad",
"dashboard": "Kontrolna tabla",
"settings": "Postavke",
"filters": "Filteri",
"filter": "Filter",
"query_log": "Dnevnik zahteva",
"compact": "Kompaktno",
"nothing_found": "Ništa nije pronađeno",
"faq": "ČPP",
"version": "Verzija",
"address": "adresa",
"address": "Adresa",
"protocol": "Protokol",
"on": "Uključeno",
"off": "Isključeno",
"copyright": "Autorska prava",
@@ -131,8 +145,10 @@
"rules_count_table_header": "Broj pravila",
"last_time_updated_table_header": "Poslednji put ažurirano",
"actions_table_header": "Radnje",
"request_table_header": "Zahtev",
"edit_table_action": "Izmeni",
"delete_table_action": "Izbriši",
"elapsed": "Proteklo",
"filters_and_hosts_hint": "AdGuard Home razume osnovna pravila blokiranja reklama i sintaksu hosts datoteke.",
"no_blocklist_added": "Blok liste nisu dodate",
"no_whitelist_added": "Liste dozvoljenih nisu dodate",
@@ -140,6 +156,7 @@
"add_allowlist": "Dodaj listu dozvoljenih",
"cancel_btn": "Otkaži",
"enter_name_hint": "Unesite ime",
"enter_url_or_path_hint": "Unesite URL ili apsolutnu putanju liste",
"check_updates_btn": "Proveri ažuriranja",
"new_blocklist": "Nova blok lista",
"new_allowlist": "Nova lista dozvoljenih",
@@ -148,6 +165,7 @@
"enter_valid_blocklist": "Unesite važeći URL do blok liste.",
"enter_valid_allowlist": "Unesite važeći URL do liste dozvoljenih.",
"form_error_url_format": "Nevažeći format Url-a",
"form_error_url_or_path_format": "URL ili apsolutna putanja do liste nije valjana",
"custom_filter_rules": "Prilagođena pravila filtriranja",
"custom_filter_rules_hint": "Unesite jedno pravilo po redu. Možete koristiti pravila blokatora reklama ili sintaksu hosts datoteke.",
"examples_title": "Primeri",
@@ -167,12 +185,15 @@
"updated_upstream_dns_toast": "Ažurirani upstream DNS serveri",
"dns_test_ok_toast": "Dati DNS serveri rade ispravno",
"dns_test_not_ok_toast": "Server \"{{key}}\": se ne može koristiti. Proverite da li ste ga ispravno uneli",
"unblock_btn": "Odblokiraj",
"block_btn": "Blokiraj",
"unblock": "Odblokiraj",
"block": "Blokiraj",
"time_table_header": "Vreme",
"date": "Datum",
"domain_name_table_header": "Ime domena",
"domain_or_client": "Domen ili klijent",
"type_table_header": "Vrsta",
"response_table_header": "Odgovor",
"response_code": "Kod odgovora",
"client_table_header": "Klijent",
"empty_response_status": "Prazno",
"show_all_filter_type": "Pokaži sve",
@@ -191,6 +212,7 @@
"query_log_filtered": "Filtrirano od {{filter}}",
"query_log_confirm_clear": "Jeste li sigurni da želite da očistite ceo dnevnik unosa?",
"query_log_cleared": "Dnevnik unosa je uspešno očišćen",
"query_log_updated": "Dnevnik zapisa je uspešno ažuriran",
"query_log_clear": "Očisti dnevnike unosa",
"query_log_retention": "Zadržavanje dnevnika unosa",
"query_log_enable": "Uključi dnevnik",
@@ -198,6 +220,8 @@
"query_log_disabled": "Dnevnik unosa je isključen ali se može konfigurisati u <0>postavkama</0>",
"query_log_strict_search": "Koristi duple navodnike za striktnu pretragu",
"query_log_retention_confirm": "Jeste li sigurni da želite da promenite zadržavanje dnevnika unosa? Ako smanjite vrednost intervala, neki podaci će biti izgubljeni",
"anonymize_client_ip": "Anonimizuj IP klijenta",
"anonymize_client_ip_desc": "Ne čuvaj punu IP adresu klijenta u dnevnicima i statistikama",
"dns_config": "Konfiguracija DNS servera",
"blocking_mode": "Način blokiranja",
"default": "Podrazumevano",
@@ -206,6 +230,9 @@
"custom_ip": "Prilagođeni IP",
"blocking_ipv4": "Blokiranje IPv4",
"blocking_ipv6": "Blokiranje IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "Plain DNS",
"form_enter_rate_limit": "Unesite ograničenje brzine",
"rate_limit": "Ograničenje brzine",
"edns_enable": "Uključi EDNS Client Subnet",
@@ -218,12 +245,14 @@
"blocking_mode_null_ip": "Null IP: Odgovara sa zero IP adresom (0.0.0.0 za A; :: za AAAA)",
"blocking_mode_custom_ip": "Prilagođeni IP: Odgovara sa ručno podešenom IP adresom",
"upstream_dns_client_desc": "AKo ovo polje ostavite prazno, AdGuard Home će koristiti servere konfigurisane u <0>DNS postavkama</0>.",
"tracker_source": "Izvor praćenja",
"source_label": "Izvor",
"found_in_known_domain_db": "Pronađeno u poznatim bazama podataka domena.",
"category_label": "Kategorija",
"rule_label": "Pravilo",
"list_label": "Lista",
"unknown_filter": "Nepoznat filter {{filterId}}",
"known_tracker": "Poznato praćenje",
"install_welcome_title": "Dobrodošli u AdGuard home!",
"install_welcome_desc": "AdGuard Home je mrežni DNS server, blokator reklama i praćenja. Dopušta vam da kontrolišete svoju čitavu mrežu i sve vaše uređaje i ne zahteva korišćenje nikakvog klijentskog programa.",
"install_settings_title": "Administratorsko web okruženje",
@@ -252,6 +281,7 @@
"install_devices_router_list_1": "Otvorite podešavanja vašeg rutera. Obično im možete pristupiti iz vašeg preglednika preko URL (kao http://192.168.0.1/ ili http://192.168.1.1/). Možda će vam biti zatraženo da unesete lozinku. Ako je ne znate ili je se ne sećate, najčešće je možete resetovati pritiskom na dugme na samom ruteru. Neki ruteri zahtevaju određenu aplikaciju, koja bi u tom slučaju već trebalo da bude instalirana na vašem računaru ili telefonu.",
"install_devices_router_list_2": "Pronađite DHCP ili DNS postavke. Potražite DNS slova pored polja koje dozvoljava dve ili tri skupine brojeva, a svaka može da sadrži četiri grupe od jedne do tri cifre.",
"install_devices_router_list_3": "Tamo unesite adrese AdGuard home servera.",
"install_devices_router_list_4": "Na nekim ruterima ne možete postaviti prilagođeni DNS server.",
"install_devices_windows_list_1": "Otvorite kontrolnu tablu iz startnog menija ili kroz Windows pretragu.",
"install_devices_windows_list_2": "Otvorite kategoriju mreža i internet a onda otiđite u centar za mrežu i deljenje.",
"install_devices_windows_list_3": "Na levoj strani ekrana pronađite Promena postavke adaptera i kliknite tu.",
@@ -340,6 +370,7 @@
"form_enter_id": "Unesite identifikator",
"form_add_id": "Dodaj identifikator",
"form_client_name": "Unesite ime klijenta",
"name": "Ime",
"client_global_settings": "Koristi globalne postavke",
"client_deleted": "Klijent \"{{key}}\" uspešno izbrisan",
"client_added": "Klijent \"{{key}}\" uspešno dodat",
@@ -384,6 +415,7 @@
"rewrite_confirm_delete": "Jeste li sigurni da želite da izbrišete DNS prepisivanje za \"{{key}}\"?",
"rewrite_desc": "Dozvoljava da jednostavno konfigurišete prilagođeni DNS odgovor za određeni domen.",
"rewrite_applied": "Primenjeno pravilo prepisivanja",
"rewrite_hosts_applied": "Prepisano od pravila hosts datoteke",
"dns_rewrites": "DNS prepisivanja",
"form_domain": "Unesite domen",
"form_answer": "Unesite IP adresu ili domen",
@@ -438,6 +470,7 @@
"location": "Lokacija",
"orgname": "Ime organizacije",
"netname": "Ime mreže",
"network": "Mreža",
"descr": "Opis",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Saznajte više</0> o stvaranju vaše lične blokliste hostova.",
@@ -448,6 +481,8 @@
"example_rewrite_wildcard": "prepiši odgovore za sve poddomene na <0>example.org</0>.",
"disable_ipv6": "Isključi IPv6",
"disable_ipv6_desc": "Ako je ovo uključeno, svi DNS unosi za IPv6 adrese (type AAAA) će biti odbačeni.",
"fastest_addr": "Najbrža IP adresa",
"fastest_addr_desc": "Pretražuje sve DNS servere i vraća najbržu IP adresu među svim odgovorima. Ovo će usporiti DNS pretragu jer moramo da čekamo na odgovore od svih DNS servera, ali će poboljšati sveukupnu povezanost.",
"autofix_warning_text": "Ako kliknete \"Popravi\", AdGuardHome će konfigurisati vaš sistem da koristi AdGuardHome DNS server.",
"autofix_warning_list": "To će izvršiti sledeće zadatke: <0>Deaktiviranje system DNSStubListener</0> <0>Set DNS server address to 127.0.0.1</0> <0>Replace symbolic link target of /etc/resolv.conf to /run/systemd/resolve/resolv.conf</0> <0>Stop DNSStubListener (reload systemd-resolved service)</0>",
"autofix_warning_result": "Kao rezultat, svi DNS zahtevi sa vašeg sistema će biti obrađeni od AdGuardHome.",
@@ -478,5 +513,21 @@
"install_static_configure": "Otkrili smo da se koristi dinamička IP adresa — <0>{{ip}}</0>. Želite li da je koristite kao vašu statičku adresu?",
"confirm_static_ip": "AdGuard Home će konfigurisati {{ip}} da bude vaša statička IP adresa. Želite li da nastavite?",
"list_updated": "{{count}} lista ažurirana",
"list_updated_plural": "{{count}} lista ažurirano"
"list_updated_plural": "{{count}} lista ažurirano",
"dnssec_enable": "Uključi DNSSEC",
"dnssec_enable_desc": "Postavlja DNSSEC zastavicu u odlaznim DNS zahtevima i proverava rezultat (DNSSEC rešavač je potreban)",
"validated_with_dnssec": "Potvrđeno sa DNSSEC",
"show_all_responses": "Svi odgovori",
"show_blocked_responses": "Blokirano",
"show_whitelisted_responses": "Na beloj listi",
"show_processed_responses": "Obrađeno",
"blocked_safebrowsing": "Blokiralo bezbedno pregledanje",
"blocked_adult_websites": "Blokiraj sajtove za odrasle",
"blocked_threats": "Blokiranih pretnji",
"allowed": "Dozvoljeno",
"filtered": "Filtrirano",
"rewritten": "Prepisano",
"safe_search": "Sigurna pretraga",
"blocklist": "Lista blokiranih",
"milliseconds_abbreviation": "ms"
}

View File

@@ -53,7 +53,7 @@
"query_log": "Förfrågningslogg",
"faq": "FAQ",
"version": "version",
"address": "adress",
"address": "Adress",
"on": "PÅ",
"off": "AV",
"copyright": "Copyright",
@@ -136,16 +136,17 @@
"example_comment_hash": "# Också en kommentar",
"example_regex_meaning": "blockera åtkomst till domäner som matchar det angivna uttrycket",
"example_upstream_regular": "vanlig DNS (över UDP)",
"example_upstream_dot": "krypterat <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a>",
"example_upstream_doh": "krypterat <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "Du kan använda <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS-stamps</a> för <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> eller <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-över-HTTPS</a>\n-resolvers",
"example_upstream_dot": "krypterat <0>DNS-over-TLS</0>",
"example_upstream_doh": "krypterat <0>DNS-over-HTTPS</0>",
"example_upstream_sdns": "Du kan använda <0>DNS-stamps</0> för <1>DNSCrypt</1> eller <2>DNS-over-HTTPS</2>-resolvers",
"example_upstream_tcp": "vanlig DNS (över UDP)",
"updated_upstream_dns_toast": "Uppdaterade uppströms-dns-servrar",
"dns_test_ok_toast": "Angivna DNS servrar fungerar korrekt",
"dns_test_not_ok_toast": "Server \"{{key}}\": kunde inte användas. Var snäll och kolla att du skrivit in rätt",
"unblock_btn": "Avblockera",
"block_btn": "Blockera",
"unblock": "Avblockera",
"block": "Blockera",
"time_table_header": "Tid",
"date": "Datum",
"domain_name_table_header": "Domännamn",
"type_table_header": "Typ",
"response_table_header": "Svar",
@@ -356,5 +357,8 @@
"netname": "Nätverksnamn",
"descr": "Beskrivning",
"whois": "Whois",
"filtering_rules_learn_more": "<0>Mer info</0> om att skapa dina egna blockeringslistor för värdar."
"filtering_rules_learn_more": "<0>Mer info</0> om att skapa dina egna blockeringslistor för värdar.",
"show_blocked_responses": "Blockerade",
"blocked_adult_websites": "Blockerade vuxensajter",
"blocked_threats": "Blockerade hot"
}

View File

@@ -149,8 +149,8 @@
"updated_upstream_dns_toast": "อัปเดตเซิร์ฟเวอร์ DNS ต้นทาง",
"dns_test_ok_toast": "เซิร์ฟเวอร์ DNS ที่ระบุทำงานอย่างถูกต้อง",
"dns_test_not_ok_toast": "เซิร์ฟเวอร์ \"{{key}}\": ไม่สามารถใช้งานได้ โปรดตรวจสอบว่าคุณเขียนถูกต้อง",
"unblock_btn": "เลิกปิดกั้น",
"block_btn": "ปิดกั้น",
"unblock": "เลิกปิดกั้น",
"block": "ปิดกั้น",
"time_table_header": "เวลา",
"domain_name_table_header": "ชื่อโดเมน",
"type_table_header": "ประเภท",
@@ -394,6 +394,7 @@
"location": "ตำแหน่ง",
"orgname": "ชื่อองค์กร",
"netname": "ชื่อเครือข่าย",
"network": "เครือข่าย",
"descr": "คำอธิบาย",
"whois": "Whois",
"filtering_rules_learn_more": "<0>เรียนรู้เพิ่มเติม</0> เกี่ยวกับการสร้างรายการปิดกั้นโฮสต์ของคุณเอง",
@@ -411,5 +412,6 @@
"tags_desc": "คุณสามารถเลือกแท็กที่สอดคล้องกับลูกค้า แท็กสามารถรวมอยู่ในกฎการกรองและอนุญาตให้คุณใช้งานได้อย่างถูกต้องมากขึ้น <0>เรียนรู้เพิ่มเติม</0>",
"form_select_tags": "เลือกแท็กเครื่อง",
"check_title": "ตรวจสอบการกรอง",
"check_desc": "ตรวจสอบว่าชื่อโฮสต์ถูกกรอง"
"check_desc": "ตรวจสอบว่าชื่อโฮสต์ถูกกรอง",
"form_enter_host": "ป้อนชื่อโฮสต์"
}

View File

@@ -37,6 +37,7 @@
"dhcp_interface_select": "DHCP arayüzünü seç",
"dhcp_hardware_address": "Donanım adresi",
"dhcp_ip_addresses": "IP adresleri",
"ip": "IP Adresi",
"dhcp_table_hostname": "Bilgisayar Adı",
"dhcp_table_expires": "Geçerlilik Tarihi",
"dhcp_warning": "Dahili DHCP sunucusunu etkinleştirmek istiyorsanız başka aktif DHCP sunucusu olmadığından emin olun. Aksi takdirde cihazlar internete bağlanamayabilir.",
@@ -49,17 +50,21 @@
"dhcp_static_leases_not_found": "Sabit DHCP kiralaması bulunamadı",
"dhcp_add_static_lease": "Sabit kiralama ekle",
"dhcp_reset": "DHCP yapılandırmasını sıfırlamak istediğinizden emin misiniz?",
"country": "Ülke",
"delete_confirm": "\"{{key}}\" silmek istediğinizden emin misiniz?",
"form_enter_hostname": "Cihaz ismi girin",
"error_details": "Hata detayları",
"client_details": "İstemci detayları",
"details": "Detaylar",
"back": "Geri",
"dashboard": "Pano",
"settings": "Ayarlar",
"filters": "Filtreler",
"filter": "Filtre",
"query_log": "Sorgu Günlüğü",
"faq": "SSS",
"version": "Sürüm",
"address": "adres",
"address": "Adres",
"on": "AÇIK",
"off": "KAPALI",
"copyright": "Tüm hakları saklıdır",
@@ -132,8 +137,10 @@
"rules_count_table_header": "Kural sayısı",
"last_time_updated_table_header": "Son güncelleme",
"actions_table_header": "Eylemler",
"request_table_header": "İstek",
"edit_table_action": "Düzenle",
"delete_table_action": "Sil",
"elapsed": "Geçen zaman",
"filters_and_hosts_hint": "AdGuard Home temel reklam engelleme kurallarını ve hosts dosyalarının söz dizim kurallarını anlamaktadır.",
"no_blocklist_added": "Hiçbir blok listesi eklenmedi",
"no_whitelist_added": "Hiçbir izin listesi eklenmedi",
@@ -170,10 +177,12 @@
"updated_upstream_dns_toast": "Üst DNS sunucuları güncellendi",
"dns_test_ok_toast": "Belirtilmiş DNS sunucuları düzgün çalışıyor",
"dns_test_not_ok_toast": "Sunucu \"{{key}}\": kullanılamıyor, lütfen doğru yazdığınızdan emin olun",
"unblock_btn": "Engeli kaldır",
"block_btn": "Engelle",
"unblock": "Engeli kaldır",
"block": "Engelle",
"time_table_header": "Saat",
"date": "Tarih",
"domain_name_table_header": "Alan adı",
"domain_or_client": "Alan adı veya istemci",
"type_table_header": "Tür",
"response_table_header": "Yanıt",
"client_table_header": "İstemci",
@@ -211,6 +220,7 @@
"custom_ip": "Özel IP",
"blocking_ipv4": "IPv4 engelleme",
"blocking_ipv6": "IPv6 engelleme",
"dns_over_https": "DNS üzerinden HTTPS",
"form_enter_rate_limit": "Sıklık limitini girin",
"rate_limit": "Sıklık limiti",
"edns_enable": "EDNS İstemci Alt Ağını Etkinleştir",
@@ -257,7 +267,7 @@
"install_devices_router_list_1": "Yönlendiricinizin ayarlarına girin. Genelde internet tarayıcınızdan bir URL vasıtasıyla erişebilirsiniz (http://192.168.0.1/ veya http://192.168.1.1/ gibi). Sizden şifre girmenizi isteyebilir. Hatırlamıyorsanız yönlendiricinizin arkasındaki 'reset' tuşuna basılı tutup fabrika ayarlarına sıfırlayabilirsiniz. Bazı yönlendiriciler belirli uygulamalarla çalışır, bu durumda bilgisayarınıza/telefonunuza kurulması gerekir.",
"install_devices_router_list_2": "DHCP/DNS ayarlarını bulun. DNS satırlarını arayın, genelde iki veya üç tanedir, üç rakam girilebilen dört ayrı grup içeren satırdır.",
"install_devices_router_list_3": "AdGuard Home sunucusunun adresini o kısma yazın.",
"install_devices_router_list_4": "Bazı yönlendirici tiplerinde özel bir DNS sunucusu ayarlayamazsınız. Bu durumda AdGuard Home'u bir DHCP sunucu olarak ayarlamanız yardımcı olabilir. Aksi halde, yönlendirici modeliniz için DNS sunucularını elle nasıl özelleştirebileceğinizi aramalısınız.",
"install_devices_router_list_4": "Bazı yönlendirici tiplerinde özel bir DNS sunucusu ayarlayamazsınız. Bu durumda AdGuard Home'u bir DHCP sunucu olarak ayarlamanız yardımcı olabilir. Aksi halde, yönlendirici modeliniz için <0>DNS sunucularını</0> elle nasıl özelleştirebileceğinizi aramalısınız.",
"install_devices_windows_list_1": "Başlat menüsünden veya Windows aramasıyla Denetim Masası'na girin.",
"install_devices_windows_list_2": "Ağ ve Internet kategorisine girin, sonra Ağ ve Paylaşım Merkezi'ne girin.",
"install_devices_windows_list_3": "Sol taraftaki Bağdaştırıcı ayarlarını değiştir ayarını bulun ve ona tıklayın.",
@@ -489,5 +499,11 @@
"list_updated": "{{count}} liste güncellendi",
"list_updated_plural": "{{count}} liste güncellendi",
"dnssec_enable": "DNSSEC'i etkinleştir",
"dnssec_enable_desc": "DNSSEC'i giden DNS sorguları için etkinleştir ve sonucu kontrol et (DNSSEC-etkin sorgulama gerekli)"
"dnssec_enable_desc": "DNSSEC'i giden DNS sorguları için etkinleştir ve sonucu kontrol et (DNSSEC-etkin sorgulama gerekli)",
"show_blocked_responses": "Engellendi",
"show_whitelisted_responses": "Beyazlisteye eklendi",
"blocked_adult_websites": "Yetişkin içerikli site engellendi",
"blocked_threats": "Engellenen Tehditler",
"allowed": "İzin verildi",
"blocklist": "Engellenen listesi"
}

View File

@@ -2,6 +2,7 @@
"client_settings": "Cài đặt máy khách",
"example_upstream_reserved": "bạn có thể chỉ định DNS ngược tuyến <0>cho một tên miền cụ thể(hoặc nhiều)</0>",
"upstream_parallel": "Sử dụng truy vấn song song để tăng tốc độ giải quyết bằng cách truy vấn đồng thời tất cả các máy chủ ngược tuyến",
"parallel_requests": "Yêu cầu song song",
"bootstrap_dns": "Máy chủ DNS Bootstrap",
"bootstrap_dns_desc": "Máy chủ DNS Bootstrap được sử dụng để phân giải địa chỉ IP của bộ phân giải DoH/DoT mà bạn chỉ định là ngược tuyến.",
"check_dhcp_servers": "Kiểm tra máy chủ DHCP",
@@ -36,6 +37,7 @@
"dhcp_interface_select": "Chọn một card mạng",
"dhcp_hardware_address": "Địa chỉ phần cứng",
"dhcp_ip_addresses": "Các địa chỉ IP",
"ip": "IP",
"dhcp_table_hostname": "Tên máy chủ",
"dhcp_table_expires": "Hết hạn",
"dhcp_warning": "Nếu bạn vẫn muốn bật máy chủ DHCP, hãy đảm bảo rằng không có máy chủ DHCP hoạt động nào khác trong mạng của bạn. Nếu không, nó có thể phá vỡ Internet cho các thiết bị được kết nối!",
@@ -48,9 +50,11 @@
"dhcp_static_leases_not_found": "Không tìm thấy DHCP cho thuê tĩnh",
"dhcp_add_static_lease": "Thêm thuê tĩnh",
"dhcp_reset": "Bạn có chắc chắn muốn đặt lại thiết lập DHCP?",
"country": "Quốc gia",
"delete_confirm": "Bạn có chắc chắn muốn xóa \"{{key}}\" không?",
"form_enter_hostname": "Nhập tên máy chủ",
"error_details": "Chi tiết lỗi",
"details": "Chi tiết",
"back": "Quay lại",
"dashboard": "Tổng quan",
"settings": "Cài đặt",
@@ -121,6 +125,7 @@
"enabled_save_search_toast": "Đã bật tìm kiếm an toàn",
"enabled_table_header": "Kích hoạt",
"name_table_header": "Tên",
"list_url_table_header": "Danh sách liên kết",
"rules_count_table_header": "Số quy tắc",
"last_time_updated_table_header": "Cập nhật cuối",
"actions_table_header": "Thao tác",
@@ -141,17 +146,18 @@
"example_comment_hash": "# Cũng là một chú thích",
"example_regex_meaning": "chặn quyền truy cập vào các miền khớp với <0>biểu thức chính được quy định</0>",
"example_upstream_regular": "DNS thông thường (dùng UDP)",
"example_upstream_dot": "được mã hoá <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a>",
"example_upstream_doh": "được mã hoá <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "bạn có thể sử dụng <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> for <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> hoặc<a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> ",
"example_upstream_dot": "được mã hoá <0>DNS-over-TLS</0>",
"example_upstream_doh": "được mã hoá <0>DNS-over-HTTPS</0>",
"example_upstream_sdns": "bạn có thể sử dụng <0>DNS Stamps</0> for <1>DNSCrypt</1> hoặc <2>DNS-over-HTTPS</2> ",
"example_upstream_tcp": "DNS thông thường(dùng TCP)",
"updated_upstream_dns_toast": "Đã cập nhật máy chủ DNS tìm kiếm",
"dns_test_ok_toast": "Máy chủ DNS có thể sử dụng",
"dns_test_not_ok_toast": "Máy chủ \"\"': không thể sử dụng, vui lòng kiểm tra lại",
"unblock_btn": "Bỏ chặn",
"block_btn": "Chặn",
"unblock": "Bỏ chặn",
"block": "Chặn",
"time_table_header": "Thời gian",
"domain_name_table_header": "Tên miền",
"domain_or_client": "Tên miền hoặc khách hàng",
"type_table_header": "Loại",
"response_table_header": "Phản hồi",
"client_table_header": "Người dùng cuối",
@@ -190,10 +196,15 @@
"blocking_ipv6": "Chặn IPv6",
"form_enter_rate_limit": "Nhập giới hạn yêu cầu",
"rate_limit": "Giới hạn yêu cầu",
"edns_cs_desc": "Nếu được bật, AdGuard Home sẽ gửi các mạng con của khách hàng đến các máy chủ DNS.",
"rate_limit_desc": "Số lượng yêu cầu mỗi giây mà một khách hàng được phép thực hiện (0: không giới hạn)",
"blocking_ipv4_desc": "Địa chỉ IP được trả lại cho một yêu cầu A bị chặn",
"blocking_mode_default": "Mặc định: Trả lời với NXDOMAIN khi bị chặn bởi quy tắc kiểu Adblock; phản hồi với địa chỉ IP được chỉ định trong quy tắc khi bị chặn bởi quy tắc / etc / hosts-style",
"source_label": "Nguồn",
"found_in_known_domain_db": "Tìm thấy trong cơ sở dữ liệu tên miền",
"category_label": "Thể loại",
"rule_label": "Quy tắc",
"list_label": "Danh sách",
"unknown_filter": "Bộ lọc không rõ {{filterId}}",
"install_welcome_title": "Chào mừng bạn đến với AdGuard Home!",
"install_welcome_desc": "AdGuard Home là một máy chủ DNS chặn quảng cáo và theo dõi trên toàn mạng. Mục đích của nó là cho phép bạn kiểm soát toàn bộ mạng và tất cả các thiết bị của mình và không yêu cầu sử dụng chương trình phía máy khách.",
@@ -412,6 +423,26 @@
"filtering_rules_learn_more": "<0>Tìm hiểu thêm</0> về việc tạo danh sách chặn máy chủ của riêng bạn.",
"blocked_by_response": "Chặn bởi CNAME hoặc địa IP ở phản hồi",
"try_again": "Hãy thử lại",
"fastest_addr_desc": "Truy vấn tất cả các máy chủ DNS và trả về địa chỉ IP nhanh nhất trong số tất cả các phản hồi",
"autofix_warning_text": "Nếu bạn nhấp vào \"Khắc phục\", AdGuard Home sẽ định cấu hình hệ thống của bạn để sử dụng máy chủ DNS của AdGuard Home.",
"autofix_warning_result": "Do đó, tất cả các yêu cầu DNS từ hệ thống của bạn sẽ được AdGuard Home xử lý theo mặc định.",
"tags_title": "Thẻ",
"tags_desc": "Bạn có thể chọn các thẻ tương ứng với khách hàng. Thẻ có thể được bao gồm trong các quy tắc lọc và cho phép bạn áp dụng chúng chính xác hơn. <0>Tìm hiểu thêm</0>",
"form_select_tags": "Chọn thẻ khách hàng",
"check_title": "Kiểm tra bộ lọc",
"check_desc": "Kiểm tra xem tên máy chủ có được lọc không",
"check": "Kiểm tra",
"check_ip": "Địa chỉ IP: {{ip}}",
"check_rule": "Quy tắc: {{rule}}",
"check_not_found": "Không tìm thấy trong danh sách bộ lọc của bạn",
"static_ip": "Địa chỉ IP tĩnh",
"dnssec_enable": "Bật DNSSEC",
"dnssec_enable_desc": "Cắm mốc DNSSEC trong các truy vấn DNS sắp tới và kiểm tra kết quả (buộc phải có trình sửa lỗi hỗ trợ DNSSEC)"
"dnssec_enable_desc": "Cắm mốc DNSSEC trong các truy vấn DNS sắp tới và kiểm tra kết quả (buộc phải có trình sửa lỗi hỗ trợ DNSSEC)",
"show_blocked_responses": "Bị chặn",
"show_whitelisted_responses": "Đã thêm vào danh sách cho phép",
"show_processed_responses": "Đã xử lý",
"blocked_adult_websites": "Website người lớn đã chặn",
"blocked_threats": "Mối nguy hiểm đã chặn",
"allowed": "Được phép",
"safe_search": "Tìm kiếm an toàn"
}

View File

@@ -3,6 +3,8 @@
"example_upstream_reserved": "您可以将上游DNS 服务器<0>指定为特定域名</0>",
"upstream_parallel": "通过同时查询所有上游服务器,使用并行请求以加速解析",
"parallel_requests": "并行请求",
"load_balancing": "负载均衡",
"load_balancing_desc": "一次查询一台服务器。 AdGuard Home将使用加权随机算法来选择服务器以便更频繁地使用最快的服务器。",
"bootstrap_dns": "Bootstrap DNS 服务器",
"bootstrap_dns_desc": "Bootstrap DNS 服务器用于解析您指定为上游的 DoH / DoT 解析器的 IP 地址。",
"check_dhcp_servers": "检查 DHCP 服务器",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "选择 DHCP 接口",
"dhcp_hardware_address": "硬件地址",
"dhcp_ip_addresses": "IP 地址",
"ip": "IP地址",
"dhcp_table_hostname": "主机名",
"dhcp_table_expires": "到期",
"dhcp_warning": "如果你想要启用内置的 DHCP 服务器,请确保在当前网络中没有其它起作用的 DHCP 服务器。否则,此操作可能会破坏已连接设备的网络连接!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "未找到 DHCP 静态租约",
"dhcp_add_static_lease": "添加静态租约",
"dhcp_reset": "您确定要重置DHCP设定么",
"country": "国家",
"city": "城市",
"delete_confirm": "您确定要删除 \"{{key}}\"",
"form_enter_hostname": "输入主机名称",
"error_details": "详细错误信息",
"response_details": "响应细节",
"request_details": "请求详情",
"client_details": "客户端详情",
"details": "详细信息",
"back": "返回",
"dashboard": "仪表盘",
"settings": "设置",
"filters": "过滤器",
"filter": "过滤器",
"query_log": "查询日志",
"compact": "紧凑",
"nothing_found": "没找到",
"faq": "常见问题",
"version": "版本",
"address": "地址",
"protocol": "协议",
"on": "启用中",
"off": "禁用中",
"copyright": "版权",
@@ -82,7 +95,7 @@
"no_domains_found": "未找到域名",
"requests_count": "请求数",
"top_blocked_domains": "被拦截域名排行",
"top_clients": "顶级客户端",
"top_clients": "客户端排行",
"no_clients_found": "未找到客户端",
"general_statistics": "概况统计",
"number_of_dns_query_days": "过去 {{count}} 天内 处理的DNS 查询总数",
@@ -114,7 +127,7 @@
"encryption_settings": "加密设置",
"dhcp_settings": "DHCP 设置",
"upstream_dns": "上游 DNS 服务器",
"upstream_dns_hint": "如果此处留空AdGuard Home 将会使用 <a href='https://www.quad9.net/' target='_blank'>Cloudflare DNS</a> 作为上游 DNS。如果想要使用 DNS over TLS请以 tls:// 为开头。",
"upstream_dns_hint": "如果此处留空AdGuard Home 将会使用 <a href='https://www.quad9.net/' target='_blank'>Quad9</a> 作为上游。",
"test_upstream_btn": "测试上游 DNS",
"upstreams": "上游服务器",
"apply_btn": "应用",
@@ -132,8 +145,10 @@
"rules_count_table_header": "规则数",
"last_time_updated_table_header": "上次更新时间",
"actions_table_header": "活跃状态",
"request_table_header": "请求",
"edit_table_action": "编辑",
"delete_table_action": "删除",
"elapsed": "耗时",
"filters_and_hosts_hint": "AdGuard Home 可以解析基础的 adblock 规则和 Hosts 语法。",
"no_blocklist_added": "未添加阻止列表",
"no_whitelist_added": "未添加允许列表",
@@ -162,20 +177,23 @@
"example_comment_hash": "# 这也是一行注释",
"example_regex_meaning": "阻止访问与<0>指定的正则表达式</0>匹配的域",
"example_upstream_regular": "常规 DNS基于 UDP",
"example_upstream_dot": "加密 <a href='https://en.wikipedia.org/wiki/DNS_over_TLS' target='_blank'>DNS-over-TLS</a>",
"example_upstream_doh": "加密 <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a>",
"example_upstream_sdns": "你可以使用 <a href='https://dnscrypt.info/' target='_blank'>DNSCrypt</a> 的 <a href='https://dnscrypt.info/stamps/' target='_blank'>DNS Stamps</a> 或者 <a href='https://en.wikipedia.org/wiki/DNS_over_HTTPS' target='_blank'>DNS-over-HTTPS</a> 解析器",
"example_upstream_dot": "加密 <0>DNS-over-TLS</0>",
"example_upstream_doh": "加密 <0>DNS-over-HTTPS</0>",
"example_upstream_sdns": "你可以使用 <1>DNSCrypt</1> 的 <0>DNS Stamps</0> 或者 <2>DNS-over-HTTPS</2> 解析器",
"example_upstream_tcp": "常规 DNS基于 TCP ",
"all_lists_up_to_date_toast": "所有列表都是最新的",
"updated_upstream_dns_toast": "上游 DNS 已更新",
"dns_test_ok_toast": "指定的 DNS 服务器现已正常运行",
"dns_test_not_ok_toast": "服务器 \"{{key}}\":无法使用,请检查你输入的是否正确",
"unblock_btn": "放行",
"block_btn": "拦截",
"unblock": "放行",
"block": "拦截",
"time_table_header": "时间",
"date": "日起",
"domain_name_table_header": "域名",
"domain_or_client": "域名或客户端",
"type_table_header": "类型",
"response_table_header": "响应",
"response_code": "响应代码",
"client_table_header": "客户端",
"empty_response_status": "空",
"show_all_filter_type": "显示所有",
@@ -194,6 +212,7 @@
"query_log_filtered": "被 {{filter}} 过滤",
"query_log_confirm_clear": "你确定想要清除全部查询日志吗?",
"query_log_cleared": "查询日志已成功清除",
"query_log_updated": "已成功更新查询日志",
"query_log_clear": "清除查询日志",
"query_log_retention": "查询记录保留时间",
"query_log_enable": "启用日志",
@@ -211,6 +230,9 @@
"custom_ip": "自定义 IP",
"blocking_ipv4": "拦截 IPv4",
"blocking_ipv6": "拦截 IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "无加密DNS",
"form_enter_rate_limit": "输入限制速率",
"rate_limit": "速度限制",
"edns_enable": "使用客户端的子网地址EDNS)",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "空IP以零IP地址响应(A记录 0.0.0.0AAAA记录 ::)",
"blocking_mode_custom_ip": "自定IP以手动设置的IP地址响应",
"upstream_dns_client_desc": "如果将此字段留空AdGuard Home 将使用在<0>DNS设置</0>中配置的服务器。",
"tracker_source": "追踪器来源",
"source_label": "源",
"found_in_known_domain_db": "成功在已知域名数据库中查询到",
"category_label": "类别",
"rule_label": "规则",
"list_label": "列表",
"unknown_filter": "未知过滤器 {{filterId}}",
"known_tracker": "已知跟踪器",
"install_welcome_title": "欢迎使用 AdGuard Home",
"install_welcome_desc": "AdGuard Home 是一个可在特定网络范围内拦截所有广告和跟踪器的 DNS 服务器。它的目的是让您控制整个网络和您的所有设备,且不需要使用任何客户端程序。",
"install_settings_title": "网页管理界面",
@@ -346,6 +370,7 @@
"form_enter_id": "输入标识符",
"form_add_id": "添加标识符",
"form_client_name": "输入客户端名称",
"name": "名称",
"client_global_settings": "使用全局设置",
"client_deleted": "客户端 \"{{key}}\" 删除成功",
"client_added": "客户端 \"{{key}}\" 添加成功",
@@ -361,7 +386,7 @@
"access_allowed_desc": "CIDR 或 IP 地址列表。如配置,则 AdGuard Home 仅会接受源自这些 IP 地址的请求。",
"access_disallowed_title": "不允许的客户端",
"access_disallowed_desc": "CIDR 或 IP 地址列表。如配置,则 AdGuard Home 会放弃源自这些 IP 地址的请求。",
"access_blocked_title": "被拦截的网域",
"access_blocked_title": "不允许的域名",
"access_blocked_desc": "不要将此功能与过滤器混淆。AdGuard Home 将在查询时删除具有这些网域的 DNS 查询。在此可以明确指定域名、通配符wildcard和网址过滤器规则例如 'example.org'、'*.example.org' 或 '||example.org^'。",
"access_settings_saved": "访问设置保存成功",
"updates_checked": "检查更新成功",
@@ -417,7 +442,7 @@
"interval_24_hour": "24 小时",
"interval_days": "{{count}} 天",
"interval_days_plural": "{{count}} 天",
"domain": "域",
"domain": "域",
"answer": "应答",
"filter_added_successfully": "已成功添加过滤器",
"filter_updated": "成功更新过滤器",
@@ -445,6 +470,7 @@
"location": "地址",
"orgname": "机构名称",
"netname": "网络名称",
"network": "网络",
"descr": "描述",
"whois": "Whois",
"filtering_rules_learn_more": "<0>了解更多</0>关于创建自己的hosts清单。",
@@ -456,7 +482,7 @@
"disable_ipv6": "禁用 IPv6",
"disable_ipv6_desc": "启用后所有IPv6地址 (type AAAA) 的DNS查询都会被丢弃。",
"fastest_addr": "最快的 IP 地址",
"fastest_addr_desc": "查询所有DNS服务器并返回所有响应中最快的IP地址",
"fastest_addr_desc": "查询所有DNS服务器并返回所有响应中速度最快的IP地址。因必须等待全部DNS服务器均有所回应因而会降低DNS查询的速度但同时此举将会改善总体的连接。",
"autofix_warning_text": "若您单击“修复”AdGuardHome将会配置您的系统以使用AdGuardHome的DNS服务器",
"autofix_warning_list": "其将会进行如下工作:<0>停用系统DNSStubListener</0><0>设置DNS服务器地址为127.0.0.1</0><0>将/etc/resolv.conf的符号链接目标替换为/run/systemd/resolv/resolv.conf</0><0>停止DNSStubListener重新加载系统解析服务</0>",
"autofix_warning_result": "因此默认情况下所有来自系统的DNS请求都将由AdGuardHome处理。",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} 列表已更新",
"list_updated_plural": "{{count}} 条列表已更新",
"dnssec_enable": "启用DNSSEC",
"dnssec_enable_desc": "在发出DNS查询中设置DNSSEC标志并检查结果(需要启用DNSSEC的解析器)"
}
"dnssec_enable_desc": "在发出DNS查询中设置DNSSEC标志并检查结果(需要启用DNSSEC的解析器)",
"validated_with_dnssec": "通过DNSSEC验证",
"show_all_responses": "所有响应",
"show_blocked_responses": "已拦截",
"show_whitelisted_responses": "已列入白名单",
"show_processed_responses": "已处理",
"blocked_safebrowsing": "被安全浏览阻止",
"blocked_adult_websites": "拦截的成人网站",
"blocked_threats": "拦截的威胁",
"allowed": "允许项",
"filtered": "已过滤",
"rewritten": "重写项",
"safe_search": "安全搜索",
"blocklist": "拦截列表",
"milliseconds_abbreviation": "毫秒"
}

View File

@@ -1,8 +1,10 @@
{
"client_settings": "用戶端設定",
"example_upstream_reserved": "您可明確指定<0>用於特定的網域</0>之 DNS 上游",
"upstream_parallel": "透過同時地查詢所有上游的伺服器,使用並行的請求以加速解析",
"upstream_parallel": "透過同時地查詢所有上游的伺服器,使用並行的查詢以加速解析網域",
"parallel_requests": "並行的請求",
"load_balancing": "負載平衡",
"load_balancing_desc": "每次查詢一個伺服器。AdGuard Home 將使用加權隨機的演算法來選擇伺服器,以便最快的伺服器將被更常使用。",
"bootstrap_dns": "自我啟動BootstrapDNS 伺服器",
"bootstrap_dns_desc": "自我啟動BootstrapDNS 伺服器被用於解析您明確指定作為上游的 DoH/DoT 解析器之 IP 位址。",
"check_dhcp_servers": "檢查動態主機設定協定DHCP伺服器",
@@ -37,6 +39,7 @@
"dhcp_interface_select": "選擇動態主機設定協定DHCP介面",
"dhcp_hardware_address": "硬體位址",
"dhcp_ip_addresses": "IP 位址",
"ip": "IP",
"dhcp_table_hostname": "主機名稱",
"dhcp_table_expires": "到期",
"dhcp_warning": "如果您無論如何想要啟用動態主機設定協定DHCP伺服器確保在您的網路中無其它現行的 DHCP 伺服器。否則,它可能會破壞供已連線的裝置之網際網路!",
@@ -49,17 +52,27 @@
"dhcp_static_leases_not_found": "無已發現之動態主機設定協定DHCP靜態租約",
"dhcp_add_static_lease": "增加靜態租約",
"dhcp_reset": "您確定您想要重置動態主機設定協定DHCP配置嗎",
"country": "國家",
"city": "城市",
"delete_confirm": "您確定您想要刪除 \"{{key}}\" 嗎?",
"form_enter_hostname": "輸入主機名稱",
"error_details": "錯誤細節",
"response_details": "回應細節",
"request_details": "請求細節",
"client_details": "用戶端細節",
"details": "細節",
"back": "返回",
"dashboard": "儀表板",
"settings": "設定",
"filters": "過濾器",
"filter": "過濾器",
"query_log": "查詢記錄",
"compact": "精簡的",
"nothing_found": "無什麼被找到",
"faq": "常見問答集",
"version": "版本",
"address": "位址",
"protocol": "協定",
"on": "開著",
"off": "關著",
"copyright": "版權",
@@ -88,7 +101,7 @@
"number_of_dns_query_days": "在最近的 {{count}} 日內已處理的 DNS 查詢之數量",
"number_of_dns_query_days_plural": "在最近的 {{count}} 日內已處理的 DNS 查詢之數量",
"number_of_dns_query_24_hours": "在最近的 24 小時內已處理的 DNS 查詢之數量",
"number_of_dns_query_blocked_24_hours": "被廣告封鎖過濾器和主機封鎖清單封鎖的 DNS 請求之數量",
"number_of_dns_query_blocked_24_hours": "被廣告封鎖過濾器和主機封鎖清單阻擋的 DNS 請求之數量",
"number_of_dns_query_blocked_24_hours_by_sec": "被 AdGuard 瀏覽安全模組封鎖的 DNS 請求之數量",
"number_of_dns_query_blocked_24_hours_adult": "已封鎖的成人網站之數量",
"enforced_save_search": "已強制執行的安全搜尋",
@@ -108,7 +121,7 @@
"dns_settings": "DNS 設定",
"dns_blocklists": "DNS 封鎖清單",
"dns_allowlists": "DNS 允許清單",
"dns_blocklists_desc": "AdGuard Home 將封鎖與封鎖清單相符的網域。",
"dns_blocklists_desc": "AdGuard Home 將阻擋與封鎖清單相符的網域。",
"dns_allowlists_desc": "即使來自 DNS 允許清單的網域在任何的封鎖清單中,它們將被允許。",
"custom_filtering_rules": "自訂的過濾規則",
"encryption_settings": "加密設定",
@@ -132,8 +145,10 @@
"rules_count_table_header": "規則總數",
"last_time_updated_table_header": "最近的更新時間",
"actions_table_header": "動作",
"request_table_header": "請求",
"edit_table_action": "編輯",
"delete_table_action": "刪除",
"elapsed": "已經過",
"filters_and_hosts_hint": "AdGuard Home 懂得基本的廣告封鎖規則和主機檔案語法。",
"no_blocklist_added": "無已加入的封鎖清單",
"no_whitelist_added": "無已加入的允許清單",
@@ -170,12 +185,15 @@
"updated_upstream_dns_toast": "已更新上游的 DNS 伺服器",
"dns_test_ok_toast": "已明確指定的 DNS 伺服器正在正確地運作",
"dns_test_not_ok_toast": "伺服器 \"{{key}}\":無法被使用,請檢查您已正確地填寫它",
"unblock_btn": "解除封鎖",
"block_btn": "封鎖",
"unblock": "解除封鎖",
"block": "封鎖",
"time_table_header": "時間",
"date": "日期",
"domain_name_table_header": "域名",
"domain_or_client": "網域或用戶端",
"type_table_header": "類型",
"response_table_header": "回應",
"response_code": "回應碼",
"client_table_header": "用戶端",
"empty_response_status": "空無的",
"show_all_filter_type": "顯示全部",
@@ -194,6 +212,7 @@
"query_log_filtered": "被 {{filter}} 過濾",
"query_log_confirm_clear": "您確定您想要清除整個查詢記錄嗎?",
"query_log_cleared": "該查詢記錄已被成功地清除",
"query_log_updated": "該查詢記錄已被成功地更新",
"query_log_clear": "清除查詢記錄",
"query_log_retention": "查詢記錄保留",
"query_log_enable": "啟用記錄",
@@ -211,6 +230,9 @@
"custom_ip": "自訂的 IP",
"blocking_ipv4": "封鎖 IPv4",
"blocking_ipv6": "封鎖 IPv6",
"dns_over_https": "DNS-over-HTTPS",
"dns_over_tls": "DNS-over-TLS",
"plain_dns": "一般的 DNS",
"form_enter_rate_limit": "輸入速率限制",
"rate_limit": "速率限制",
"edns_enable": "啟用對於 DNS 的擴充機制EDNS用戶端子網路",
@@ -223,12 +245,14 @@
"blocking_mode_null_ip": "無效的 IP以零值 IP 位址0.0.0.0 供 A:: 供 AAAA回覆",
"blocking_mode_custom_ip": "自訂的 IP以一組手動地被設定的 IP 位址回覆",
"upstream_dns_client_desc": "如果您將該欄位留空AdGuard Home 將使用在 <0>DNS 設定</0>中被配置的伺服器。",
"tracker_source": "追蹤器來源",
"source_label": "來源",
"found_in_known_domain_db": "在已知的域名資料庫中被發現。",
"category_label": "類別",
"rule_label": "規則",
"list_label": "清單",
"unknown_filter": "未知的過濾器 {{filterId}}",
"known_tracker": "已知的追蹤器",
"install_welcome_title": "歡迎至 AdGuard Home",
"install_welcome_desc": "AdGuard Home 是全網路範圍廣告和追蹤器封鎖的 DNS 伺服器。它的目的為讓您控制您的整個網路和所有您的裝置,且不需要使用用戶端程式。",
"install_settings_title": "管理員網路介面",
@@ -257,7 +281,7 @@
"install_devices_router_list_1": "開啟關於您的路由器之偏好設定。通常地,您可透過網址(如 http://192.168.0.1/ 或 http://192.168.1.1/)從您的瀏覽器中存取它。您可能被要求輸入該密碼。如果您不記得它,您經常可透過按壓於該路由器本身上的按鈕來重置密碼。某些路由器需要特定的應用程式,既然如此其應已被安裝於您的電腦/手機上。",
"install_devices_router_list_2": "找到 DHCP/DNS 設定。尋找緊鄰著允許兩組或三組數字集的欄位之 DNS 字母,每組被拆成四個含有一至三個數字的群集。",
"install_devices_router_list_3": "在那裡輸入您的 AdGuard Home 伺服器位址。",
"install_devices_router_list_4": "您無法於某些類型的路由器上設定自訂的 DNS 伺服器。在這種情況下,如果您設置 AdGuard Home 作為 DHCP 伺服器,其可能有所幫助。否則,您應搜尋有關如何為您的特定路由器型號自訂 DNS 伺服器之用法說明。",
"install_devices_router_list_4": "您無法於某些類型的路由器上設定自訂的 DNS 伺服器。在這種情況下,如果您設置 AdGuard Home 作為 <0>DHCP 伺服器</0>,其可能有所幫助。否則,您應搜尋有關如何為您的特定路由器型號自訂 DNS 伺服器之用法說明。",
"install_devices_windows_list_1": "通過開始功能表或 Windows 搜尋,開啟控制台。",
"install_devices_windows_list_2": "去網路和網際網路類別,然後去網路和共用中心。",
"install_devices_windows_list_3": "於畫面之左側上找到變更介面卡設定並於它上點擊。",
@@ -346,6 +370,7 @@
"form_enter_id": "輸入識別碼",
"form_add_id": "增加識別碼",
"form_client_name": "輸入用戶端名稱",
"name": "名稱",
"client_global_settings": "使用全域的設定",
"client_deleted": "用戶端 \"{{key}}\" 被成功地刪除",
"client_added": "用戶端 \"{{key}}\" 被成功地加入",
@@ -445,6 +470,7 @@
"location": "位置",
"orgname": "組織名稱",
"netname": "網路名稱",
"network": "網路",
"descr": "說明",
"whois": "Whois",
"filtering_rules_learn_more": "<0>了解更多</0>有關創建您自己的主機hosts清單。",
@@ -456,7 +482,7 @@
"disable_ipv6": "禁用 IPv6",
"disable_ipv6_desc": "如果此功能被啟用,所有對於 IPv6 位址(類型 AAAA的 DNS 查詢將被丟棄。",
"fastest_addr": "最快的 IP 位址",
"fastest_addr_desc": "查詢所有的 DNS 伺服器並返回在所有的回應之中最快的 IP 位址",
"fastest_addr_desc": "查詢所有的 DNS 伺服器並返回在所有的回應之中最快的 IP 位址。因為我們必須等待來自所有的 DNS 伺服器之回應,這將使 DNS 查詢變慢,但改善總體的連線。",
"autofix_warning_text": "如果您點擊\"修復\"AdGuard Home 將配置您的系統使用 AdGuard Home DNS 伺服器。",
"autofix_warning_list": "它將執行這些任務:<0>撤銷系統 DNSStubListener</0> <0>設定 DNS 伺服器位址為 127.0.0.1</0> <0>用 /run/systemd/resolve/resolv.conf 取代 /etc/resolv.conf 的符號連結目標</0> <0>停止 DNSStubListener重新載入 systemd 已解析的服務)</0>",
"autofix_warning_result": "因此,預設下,來自您的系統之所有的 DNS 請求將被 AdGuard Home 處理。",
@@ -474,7 +500,7 @@
"check_reason": "原因:{{reason}}",
"check_rule": "規則:{{rule}}",
"check_service": "服務名稱:{{service}}",
"check_not_found": "未在您的過濾器清單中被找到",
"check_not_found": "未在您的過濾器中被找到",
"client_confirm_block": "您確定您想要封鎖該用戶端 \"{{ip}}\" 嗎?",
"client_confirm_unblock": "您確定您想要解除封鎖該用戶端 \"{{ip}}\" 嗎?",
"client_blocked": "用戶端 \"{{ip}}\" 被成功地封鎖",
@@ -489,5 +515,19 @@
"list_updated": "{{count}} 清單被更新",
"list_updated_plural": "{{count}} 清單被更新",
"dnssec_enable": "啟用網域名稱系統安全性擴充功能DNSSEC",
"dnssec_enable_desc": "在發出的 DNS 查詢中設定 DNSSEC 標記並檢查該結果(已啟用 DNSSEC 的解析器是必須的)"
"dnssec_enable_desc": "在發出的 DNS 查詢中設定 DNSSEC 標記並檢查該結果(已啟用 DNSSEC 的解析器是必須的)",
"validated_with_dnssec": "已用網域名稱系統安全性擴充功能DNSSEC驗證",
"show_all_responses": "所有的回應",
"show_blocked_responses": "已封鎖的",
"show_whitelisted_responses": "已列入白名單的",
"show_processed_responses": "已處理的",
"blocked_safebrowsing": "被安全瀏覽封鎖",
"blocked_adult_websites": "已封鎖的成人網站",
"blocked_threats": "已封鎖的威脅",
"allowed": "已允許的",
"filtered": "已過濾的",
"rewritten": "已改寫的",
"safe_search": "安全搜尋",
"blocklist": "封鎖清單",
"milliseconds_abbreviation": "ms"
}

View File

@@ -3,8 +3,8 @@ import i18next from 'i18next';
import apiClient from '../api/Api';
import { normalizeTextarea } from '../helpers/helpers';
import { ACTION } from '../helpers/constants';
import { addErrorToast, addSuccessToast } from './toasts';
import { BLOCK_ACTIONS } from '../helpers/constants';
export const getAccessListRequest = createAction('GET_ACCESS_LIST_REQUEST');
export const getAccessListFailure = createAction('GET_ACCESS_LIST_FAILURE');
@@ -57,9 +57,9 @@ export const toggleClientBlock = (type, ip) => async (dispatch) => {
} = await apiClient.getAccessList();
let updatedDisallowedClients = disallowed_clients || [];
if (type === ACTION.unblock && updatedDisallowedClients.includes(ip)) {
if (type === BLOCK_ACTIONS.UNBLOCK && updatedDisallowedClients.includes(ip)) {
updatedDisallowedClients = updatedDisallowedClients.filter((client) => client !== ip);
} else if (type === ACTION.block && !updatedDisallowedClients.includes(ip)) {
} else if (type === BLOCK_ACTIONS.BLOCK && !updatedDisallowedClients.includes(ip)) {
updatedDisallowedClients.push(ip);
}
@@ -72,9 +72,9 @@ export const toggleClientBlock = (type, ip) => async (dispatch) => {
await apiClient.setAccessList(values);
dispatch(toggleClientBlockSuccess(values));
if (type === ACTION.unblock) {
if (type === BLOCK_ACTIONS.UNBLOCK) {
dispatch(addSuccessToast(i18next.t('client_unblocked', { ip })));
} else if (type === ACTION.block) {
} else if (type === BLOCK_ACTIONS.BLOCK) {
dispatch(addSuccessToast(i18next.t('client_blocked', { ip })));
}
} catch (error) {

View File

@@ -45,12 +45,14 @@ export const addFilterRequest = createAction('ADD_FILTER_REQUEST');
export const addFilterFailure = createAction('ADD_FILTER_FAILURE');
export const addFilterSuccess = createAction('ADD_FILTER_SUCCESS');
export const addFilter = (url, name, whitelist = false) => async (dispatch) => {
export const addFilter = (url, name, whitelist = false) => async (dispatch, getState) => {
dispatch(addFilterRequest());
try {
await apiClient.addFilter({ url, name, whitelist });
dispatch(addFilterSuccess(url));
dispatch(toggleFilteringModal());
if (getState().filtering.isModalOpen) {
dispatch(toggleFilteringModal());
}
dispatch(addSuccessToast('filter_added_successfully'));
dispatch(getFilteringStatus());
} catch (error) {
@@ -63,11 +65,15 @@ export const removeFilterRequest = createAction('REMOVE_FILTER_REQUEST');
export const removeFilterFailure = createAction('REMOVE_FILTER_FAILURE');
export const removeFilterSuccess = createAction('REMOVE_FILTER_SUCCESS');
export const removeFilter = (url, whitelist = false) => async (dispatch) => {
export const removeFilter = (url, whitelist = false) => async (dispatch, getState) => {
dispatch(removeFilterRequest());
try {
await apiClient.removeFilter({ url, whitelist });
dispatch(removeFilterSuccess(url));
if (getState().filtering.isModalOpen) {
dispatch(toggleFilteringModal());
}
dispatch(addSuccessToast('filter_removed_successfully'));
dispatch(getFilteringStatus());
} catch (error) {
dispatch(addErrorToast({ error }));
@@ -95,12 +101,14 @@ export const editFilterRequest = createAction('EDIT_FILTER_REQUEST');
export const editFilterFailure = createAction('EDIT_FILTER_FAILURE');
export const editFilterSuccess = createAction('EDIT_FILTER_SUCCESS');
export const editFilter = (url, data, whitelist = false) => async (dispatch) => {
export const editFilter = (url, data, whitelist = false) => async (dispatch, getState) => {
dispatch(editFilterRequest());
try {
await apiClient.setFilterUrl({ url, data, whitelist });
dispatch(editFilterSuccess(url));
dispatch(toggleFilteringModal());
if (getState().filtering.isModalOpen) {
dispatch(toggleFilteringModal());
}
dispatch(addSuccessToast('filter_updated'));
dispatch(getFilteringStatus());
} catch (error) {

View File

@@ -70,9 +70,18 @@ export const initSettings = (settingsList) => async (dispatch) => {
safesearch,
} = settingsList;
const newSettingsList = {
safebrowsing: { ...safebrowsing, enabled: safebrowsingStatus.enabled },
parental: { ...parental, enabled: parentalStatus.enabled },
safesearch: { ...safesearch, enabled: safesearchStatus.enabled },
safebrowsing: {
...safebrowsing,
enabled: safebrowsingStatus.enabled,
},
parental: {
...parental,
enabled: parentalStatus.enabled,
},
safesearch: {
...safesearch,
enabled: safesearchStatus.enabled,
},
};
dispatch(initSettingsSuccess({ settingsList: newSettingsList }));
} catch (error) {
@@ -140,7 +149,7 @@ const checkStatus = async (handleRequestSuccess, handleRequestError, attempts =
try {
const response = await axios.get('control/status');
rmTimeout(timeout);
if (response && response.status === 200) {
if (response?.status === 200) {
handleRequestSuccess(response);
if (response.data.running === false) {
timeout = setTimeout(
@@ -174,7 +183,7 @@ export const getUpdate = () => async (dispatch, getState) => {
};
const handleRequestSuccess = (response) => {
const responseVersion = response.data && response.data.version;
const responseVersion = response.data?.version;
if (dnsVersion !== responseVersion) {
dispatch(getUpdateSuccess());
@@ -274,13 +283,14 @@ export const testUpstream = (config) => async (dispatch) => {
values.upstream_dns = normalizeTextarea(values.upstream_dns);
const upstreamResponse = await apiClient.testUpstream(values);
const testMessages = Object.keys(upstreamResponse).map((key) => {
const message = upstreamResponse[key];
if (message !== 'OK') {
dispatch(addErrorToast({ error: i18next.t('dns_test_not_ok_toast', { key }) }));
}
return message;
});
const testMessages = Object.keys(upstreamResponse)
.map((key) => {
const message = upstreamResponse[key];
if (message !== 'OK') {
dispatch(addErrorToast({ error: i18next.t('dns_test_not_ok_toast', { key }) }));
}
return message;
});
if (testMessages.every((message) => message === 'OK')) {
dispatch(addSuccessToast('dns_test_ok_toast'));
@@ -393,11 +403,17 @@ export const toggleDhcpSuccess = createAction('TOGGLE_DHCP_SUCCESS');
export const toggleDhcp = (values) => async (dispatch) => {
dispatch(toggleDhcpRequest());
let config = { ...values, enabled: false };
let config = {
...values,
enabled: false,
};
let successMessage = 'disabled_dhcp';
if (!values.enabled) {
config = { ...values, enabled: true };
config = {
...values,
enabled: true,
};
successMessage = 'enabled_dhcp';
dispatch(findActiveDhcp(values.interface_name));
}

View File

@@ -2,20 +2,23 @@ import { createAction } from 'redux-actions';
import apiClient from '../api/Api';
import { normalizeLogs, getParamsForClientsSearch, addClientInfo } from '../helpers/helpers';
import { TABLE_DEFAULT_PAGE_SIZE } from '../helpers/constants';
import { TABLE_DEFAULT_PAGE_SIZE, TABLE_FIRST_PAGE } from '../helpers/constants';
import { addErrorToast, addSuccessToast } from './toasts';
const getLogsWithParams = async (config) => {
const { older_than, filter, ...values } = config;
const rawLogs = await apiClient.getQueryLog({ ...filter, older_than });
const { data, oldest } = rawLogs;
const logs = normalizeLogs(data);
let logs = normalizeLogs(data);
const clientsParams = getParamsForClientsSearch(logs, 'client');
const clients = await apiClient.findClients(clientsParams);
const logsWithClientInfo = addClientInfo(logs, clients, 'client');
if (Object.keys(clientsParams).length > 0) {
const clients = await apiClient.findClients(clientsParams);
logs = addClientInfo(logs, clients, 'client');
}
return {
logs: logsWithClientInfo, oldest, older_than, filter, ...values,
logs, oldest, older_than, filter, ...values,
};
};
@@ -56,6 +59,7 @@ const checkFilteredLogs = async (data, filter, dispatch, total) => {
export const setLogsPagination = createAction('LOGS_PAGINATION');
export const setLogsPage = createAction('SET_LOG_PAGE');
export const toggleDetailedLogs = createAction('TOGGLE_DETAILED_LOGS');
export const getLogsRequest = createAction('GET_LOGS_REQUEST');
export const getLogsFailure = createAction('GET_LOGS_FAILURE');
@@ -93,7 +97,7 @@ export const setLogsFilter = (filter) => async (dispatch) => {
const updatedData = additionalData.logs ? { ...data, ...additionalData } : data;
dispatch(setLogsFilterSuccess({ ...updatedData, filter }));
dispatch(setLogsPage(0));
dispatch(setLogsPage(TABLE_FIRST_PAGE));
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(setLogsFilterFailure(error));

View File

@@ -1,4 +1,9 @@
:root {
--yellow-pale: rgba(247, 181, 0, 0.1);
--green79: #67B279;
--gray-a5: #a5a5a5;
--gray-d8: #d8d8d8;
--gray-f3: #F3F3F3;
--font-family-monospace: Monaco, Menlo, "Ubuntu Mono", Consolas, source-code-pro, monospace;
}
@@ -22,6 +27,16 @@ body {
}
}
@media screen and (max-width: 992px) {
.container {
padding: 0 !important;
}
.container--wrap {
min-height: calc(100vh);
}
}
.loading-bar {
position: fixed;
top: 0;
@@ -31,10 +46,26 @@ body {
background: linear-gradient(45deg, rgba(99, 125, 120, 1) 0%, rgba(88, 177, 101, 1) 100%);
}
.hidden {
display: none;
@media (max-width: 575px) {
.container {
padding-right: 0;
padding-left: 0;
}
}
.modal-body--medium {
max-height: 20rem;
overflow-y: scroll;
}
.modal-body__item:not(:first-child) {
padding-top: 1.5rem;
}
.font-monospace {
font-family: var(--font-family-monospace);
}
.mw-75 {
max-width: 75% !important;
}

View File

@@ -34,6 +34,9 @@ import EncryptionTopline from '../ui/EncryptionTopline';
import Icons from '../ui/Icons';
import i18n from '../../i18n';
import Loading from '../ui/Loading';
import { FILTERS_URLS, MENU_URLS, SETTINGS_URLS } from '../../helpers/constants';
import Services from '../Filters/Services';
import { setHtmlLangAttr } from '../../helpers/helpers';
class App extends Component {
componentDidMount() {
@@ -60,6 +63,7 @@ class App extends Component {
if (!processing) {
if (language) {
i18n.changeLanguage(language);
setHtmlLangAttr(language);
}
}
@@ -92,33 +96,36 @@ class App extends Component {
)}
<LoadingBar className="loading-bar" updateTime={1000} />
<Route component={Header} />
<div className="container container--wrap">
<div className="container container--wrap pb-5">
{dashboard.processing && <Loading />}
{!dashboard.isCoreRunning && (
<div className="row row-cards">
<div className="col-lg-12">
<Status reloadPage={this.reloadPage}
message="dns_start"
/>
/>
<Loading />
</div>
</div>
)}
{!dashboard.processing && dashboard.isCoreRunning && (
<Fragment>
<Route path="/" exact component={Dashboard} />
<Route path="/settings" component={Settings} />
<Route path="/dns" component={Dns} />
<Route path="/encryption" component={Encryption} />
<Route path="/dhcp" component={Dhcp} />
<Route path="/clients" component={Clients} />
<Route path="/filters" component={DnsBlocklist} />
<Route path="/dns_allowlists" component={DnsAllowlist} />
<Route path="/dns_rewrites" component={DnsRewrites} />
<Route path="/custom_rules" component={CustomRules} />
<Route path="/logs" component={Logs} />
<Route path="/guide" component={SetupGuide} />
</Fragment>
<>
<Route path={MENU_URLS.root} exact component={Dashboard} />
<Route path={MENU_URLS.logs} component={Logs} />
<Route path={MENU_URLS.guide} component={SetupGuide} />
<Route path={SETTINGS_URLS.settings} component={Settings} />
<Route path={SETTINGS_URLS.dns} component={Dns} />
<Route path={SETTINGS_URLS.encryption} component={Encryption} />
<Route path={SETTINGS_URLS.dhcp} component={Dhcp} />
<Route path={SETTINGS_URLS.clients} component={Clients} />
<Route path={FILTERS_URLS.dns_blocklists}
component={DnsBlocklist} />
<Route path={FILTERS_URLS.dns_allowlists}
component={DnsAllowlist} />
<Route path={FILTERS_URLS.dns_rewrites} component={DnsRewrites} />
<Route path={FILTERS_URLS.custom_rules} component={CustomRules} />
<Route path={FILTERS_URLS.blocked_services} component={Services} />
</>
)}
</div>
<Footer

View File

@@ -1,4 +1,4 @@
import React, { Fragment } from 'react';
import React from 'react';
import ReactTable from 'react-table';
import PropTypes from 'prop-types';
import { Trans, withTranslation } from 'react-i18next';
@@ -32,17 +32,17 @@ const renderBlockingButton = (ipMatchListStatus, ip, handleClick, processing) =>
const buttonProps = ipMatchListStatus === IP_MATCH_LIST_STATUS.NOT_FOUND
? {
className: 'btn-outline-danger',
text: 'block_btn',
text: 'block',
type: 'block',
}
: {
className: 'btn-outline-secondary',
text: 'unblock_btn',
text: 'unblock',
type: 'unblock',
};
return (
<div className="table__action">
<div className="table__action button__action">
<button
type="button"
className={`btn btn-sm ${buttonProps.className}`}
@@ -60,13 +60,13 @@ const clientCell = (t, toggleClientStatus, processing, disallowedClients) => fun
const ipMatchListStatus = getIpMatchListStatus(value, disallowedClients);
return (
<Fragment>
<>
<div className="logs__row logs__row--overflow logs__row--column">
{formatClientCell(row, t)}
</div>
{ipMatchListStatus !== IP_MATCH_LIST_STATUS.CIDR
&& renderBlockingButton(ipMatchListStatus, value, toggleClientStatus, processing)}
</Fragment>
</>
);
};

View File

@@ -10,7 +10,7 @@ import BlockedDomains from './BlockedDomains';
import PageTitle from '../ui/PageTitle';
import Loading from '../ui/Loading';
import { ACTION } from '../../helpers/constants';
import { BLOCK_ACTIONS } from '../../helpers/constants';
import './Dashboard.css';
class Dashboard extends Component {
@@ -42,7 +42,7 @@ class Dashboard extends Component {
};
toggleClientStatus = (type, ip) => {
const confirmMessage = type === ACTION.block ? 'client_confirm_block' : 'client_confirm_unblock';
const confirmMessage = type === BLOCK_ACTIONS.BLOCK ? 'client_confirm_block' : 'client_confirm_unblock';
if (window.confirm(this.props.t(confirmMessage, { ip }))) {
this.props.toggleClientBlock(type, ip);

View File

@@ -7,6 +7,7 @@ import Card from '../../ui/Card';
import { renderInputField } from '../../../helpers/form';
import Info from './Info';
import { FORM_NAME } from '../../../helpers/constants';
const Check = (props) => {
const {
@@ -60,7 +61,7 @@ const Check = (props) => {
</div>
{check.hostname && (
<Fragment>
<hr/>
<hr />
<Info
filters={filters}
whitelistFilters={whitelistFilters}
@@ -94,5 +95,5 @@ Check.propTypes = {
export default flow([
withTranslation(),
reduxForm({ form: 'domainCheckForm' }),
reduxForm({ form: FORM_NAME.DOMAIN_CHECK }),
])(Check);

View File

@@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
@@ -21,7 +21,7 @@ class DnsAllowlist extends Component {
const { filtering } = this.props;
const whitelist = true;
if (filtering.modalType === MODAL_TYPE.EDIT) {
if (filtering.modalType === MODAL_TYPE.EDIT_FILTERS) {
this.props.editFilter(filtering.modalFilterUrl, values, whitelist);
} else {
this.props.addFilter(url, name, whitelist);
@@ -44,6 +44,10 @@ class DnsAllowlist extends Component {
this.props.refreshFilters({ whitelist: true });
};
openAddFiltersModal = () => {
this.props.toggleFilteringModal({ type: MODAL_TYPE.ADD_FILTERS });
};
render() {
const {
t,
@@ -72,7 +76,7 @@ class DnsAllowlist extends Component {
const whitelist = true;
return (
<Fragment>
<>
<PageTitle
title={t('dns_allowlists')}
subtitle={t('dns_allowlists_desc')}
@@ -92,7 +96,7 @@ class DnsAllowlist extends Component {
whitelist={whitelist}
/>
<Actions
handleAdd={() => toggleFilteringModal({ type: MODAL_TYPE.ADD })}
handleAdd={this.openAddFiltersModal}
handleRefresh={this.handleRefresh}
processingRefreshFilters={processingRefreshFilters}
whitelist={whitelist}
@@ -102,8 +106,9 @@ class DnsAllowlist extends Component {
</div>
</div>
<Modal
filters={whitelistFilters}
isOpen={isModalOpen}
toggleModal={toggleFilteringModal}
toggleFilteringModal={toggleFilteringModal}
addFilter={addFilter}
isFilterAdded={isFilterAdded}
processingAddFilter={processingAddFilter}
@@ -113,7 +118,7 @@ class DnsAllowlist extends Component {
currentFilterData={currentFilterData}
whitelist={whitelist}
/>
</Fragment>
</>
);
}
}

View File

@@ -1,4 +1,4 @@
import React, { Component, Fragment } from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
@@ -6,24 +6,47 @@ import PageTitle from '../ui/PageTitle';
import Card from '../ui/Card';
import Modal from './Modal';
import Actions from './Actions';
import Table from './Table';
import Table from './Table';
import { MODAL_TYPE } from '../../helpers/constants';
import { getCurrentFilter } from '../../helpers/helpers';
import {
getCurrentFilter,
getObjDiff,
} from '../../helpers/helpers';
const filtersCatalog = require('../../helpers/filters/filters.json');
class DnsBlocklist extends Component {
componentDidMount() {
this.props.getFilteringStatus();
}
handleSubmit = (values) => {
const { name, url } = values;
const { filtering } = this.props;
handleSubmit = (values, _, { initialValues }) => {
const { filtering: { modalFilterUrl, modalType } } = this.props;
if (filtering.modalType === MODAL_TYPE.EDIT) {
this.props.editFilter(filtering.modalFilterUrl, values);
} else {
this.props.addFilter(url, name);
switch (modalType) {
case MODAL_TYPE.EDIT_FILTERS:
this.props.editFilter(modalFilterUrl, values);
break;
case MODAL_TYPE.ADD_FILTERS: {
const { name, url } = values;
this.props.addFilter(url, name);
break;
}
case MODAL_TYPE.CHOOSE_FILTERING_LIST: {
const changedValues = getObjDiff(initialValues, values);
Object.keys(changedValues)
.forEach((fieldName) => {
// filterId is actually in the field name
const { source, name } = filtersCatalog.filters[fieldName];
this.props.addFilter(source, name);
});
break;
}
default:
break;
}
};
@@ -41,6 +64,10 @@ class DnsBlocklist extends Component {
this.props.refreshFilters({ whitelist: false });
};
openSelectTypeModal = () => {
this.props.toggleFilteringModal({ type: MODAL_TYPE.SELECT_MODAL_TYPE });
};
render() {
const {
t,
@@ -67,7 +94,7 @@ class DnsBlocklist extends Component {
|| processingRefreshFilters;
return (
<Fragment>
<>
<PageTitle
title={t('dns_blocklists')}
subtitle={t('dns_blocklists_desc')}
@@ -85,7 +112,7 @@ class DnsBlocklist extends Component {
toggleFilter={this.toggleFilter}
/>
<Actions
handleAdd={() => toggleFilteringModal({ type: MODAL_TYPE.ADD })}
handleAdd={this.openSelectTypeModal}
handleRefresh={this.handleRefresh}
processingRefreshFilters={processingRefreshFilters}
/>
@@ -94,8 +121,10 @@ class DnsBlocklist extends Component {
</div>
</div>
<Modal
filtersCatalog={filtersCatalog}
filters={filters}
isOpen={isModalOpen}
toggleModal={toggleFilteringModal}
toggleFilteringModal={toggleFilteringModal}
addFilter={addFilter}
isFilterAdded={isFilterAdded}
processingAddFilter={processingAddFilter}
@@ -104,7 +133,7 @@ class DnsBlocklist extends Component {
modalType={modalType}
currentFilterData={currentFilterData}
/>
</Fragment>
</>
);
}
}

View File

@@ -1,10 +1,75 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import classNames from 'classnames';
import { validatePath, validateRequiredValue } from '../../helpers/validators';
import { renderInputField, renderSelectField } from '../../helpers/form';
import { MODAL_OPEN_TIMEOUT, MODAL_TYPE, FORM_NAME } from '../../helpers/constants';
import { renderInputField, required, isValidPath } from '../../helpers/form';
const getIconsData = (homepage, source) => ([
{
iconName: 'dashboard',
href: homepage,
className: 'ml-1',
},
{
iconName: 'info',
href: source,
},
]);
const renderIcons = (iconsData) => iconsData.map(({
iconName,
href,
className = '',
}) => <a key={iconName} href={href} target="_blank" rel="noopener noreferrer"
className={classNames('d-flex align-items-center', className)}
>
<svg className="nav-icon nav-icon--gray">
<use xlinkHref={`#${iconName}`} />
</svg>
</a>);
const renderFilters = ({ categories, filters }, selectedSources, t) => Object.keys(categories)
.map((categoryId) => {
const category = categories[categoryId];
const categoryFilters = [];
Object.keys(filters)
.sort()
.forEach((key) => {
const filter = filters[key];
filter.id = key;
if (filter.categoryId === categoryId) {
categoryFilters.push(filter);
}
});
return <div key={category.name} className="modal-body__item">
<h6 className="font-weight-bold mb-1">{t(category.name)}</h6>
<p className="mb-3">{t(category.description)}</p>
{categoryFilters.map((filter) => {
const { homepage, source, name } = filter;
const isSelected = Object.prototype.hasOwnProperty.call(selectedSources, source);
const iconsData = getIconsData(homepage, source);
return <div key={name} className="d-flex align-items-center pb-1">
<Field
name={`${filter.id}`}
type="checkbox"
component={renderSelectField}
placeholder={t(name)}
disabled={isSelected}
checked={isSelected}
/>
{renderIcons(iconsData)}
</div>;
})}
</div>;
});
const Form = (props) => {
const {
@@ -14,23 +79,50 @@ const Form = (props) => {
processingAddFilter,
processingConfigFilter,
whitelist,
modalType,
toggleFilteringModal,
selectedSources,
filtersCatalog,
} = props;
return (
<form onSubmit={handleSubmit}>
<div className="modal-body">
<div className="form__group">
<Field
id="name"
name="name"
type="text"
component={renderInputField}
className="form-control"
placeholder={t('enter_name_hint')}
validate={[required]}
normalizeOnBlur={(data) => data.trim()}
/>
</div>
const openModal = (modalType, timeout = MODAL_OPEN_TIMEOUT) => {
toggleFilteringModal();
setTimeout(() => toggleFilteringModal({ type: modalType }), timeout);
};
const openFilteringListModal = () => openModal(MODAL_TYPE.CHOOSE_FILTERING_LIST);
const openAddFiltersModal = () => openModal(MODAL_TYPE.ADD_FILTERS);
return <form onSubmit={handleSubmit}>
<div className="modal-body modal-body--medium">
{modalType === MODAL_TYPE.SELECT_MODAL_TYPE
&& <div className="d-flex justify-content-around">
<button onClick={openFilteringListModal}
className="btn btn-success btn-standard mr-2 btn-large">
{t('choose_from_list')}
</button>
<button onClick={openAddFiltersModal} className="btn btn-primary btn-standard">
{t('add_custom_list')}
</button>
</div>}
{modalType === MODAL_TYPE.CHOOSE_FILTERING_LIST
&& renderFilters(filtersCatalog, selectedSources, t)}
{modalType !== MODAL_TYPE.CHOOSE_FILTERING_LIST
&& modalType !== MODAL_TYPE.SELECT_MODAL_TYPE
&& <>
<div className="form__group">
<Field
id="name"
name="name"
type="text"
component={renderInputField}
className="form-control"
placeholder={t('enter_name_hint')}
validate={[validateRequiredValue]}
normalizeOnBlur={(data) => data.trim()}
/>
</div>
<div className="form__group">
<Field
id="url"
@@ -39,33 +131,32 @@ const Form = (props) => {
component={renderInputField}
className="form-control"
placeholder={t('enter_url_or_path_hint')}
validate={[required, isValidPath]}
validate={[validateRequiredValue, validatePath]}
normalizeOnBlur={(data) => data.trim()}
/>
</div>
<div className="form__description">
{whitelist ? <Trans>enter_valid_allowlist</Trans>
: <Trans>enter_valid_blocklist</Trans>}
{whitelist ? t('enter_valid_allowlist') : t('enter_valid_blocklist')}
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-secondary"
onClick={closeModal}
>
<Trans>cancel_btn</Trans>
</button>
<button
type="submit"
className="btn btn-success"
disabled={processingAddFilter || processingConfigFilter}
>
<Trans>save_btn</Trans>
</button>
</div>
</form>
);
</>}
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-secondary"
onClick={closeModal}
>
{t('cancel_btn')}
</button>
<button
type="submit"
className="btn btn-success"
disabled={processingAddFilter || processingConfigFilter}
>
{t('save_btn')}
</button>
</div>
</form>;
};
Form.propTypes = {
@@ -75,11 +166,13 @@ Form.propTypes = {
processingAddFilter: PropTypes.bool.isRequired,
processingConfigFilter: PropTypes.bool.isRequired,
whitelist: PropTypes.bool,
modalType: PropTypes.string.isRequired,
toggleFilteringModal: PropTypes.func.isRequired,
filtersCatalog: PropTypes.object,
selectedSources: PropTypes.object,
};
export default flow([
withTranslation(),
reduxForm({
form: 'filterForm',
}),
reduxForm({ form: FORM_NAME.FILTER }),
])(Form);

View File

@@ -1,17 +1,51 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactModal from 'react-modal';
import { Trans, withTranslation } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { MODAL_TYPE } from '../../helpers/constants';
import Form from './Form';
import '../ui/Modal.css';
import { getMap } from '../../helpers/helpers';
ReactModal.setAppElement('#root');
const MODAL_TYPE_TO_TITLE_TYPE_MAP = {
[MODAL_TYPE.EDIT_FILTERS]: 'edit',
[MODAL_TYPE.ADD_FILTERS]: 'new',
[MODAL_TYPE.SELECT_MODAL_TYPE]: 'new',
[MODAL_TYPE.CHOOSE_FILTERING_LIST]: 'choose',
};
/**
* @param modalType {'EDIT_FILTERS' | 'ADD_FILTERS' | 'CHOOSE_FILTERING_LIST'}
* @param whitelist {boolean}
* @returns {'new_allowlist' | 'edit_allowlist' | 'choose_allowlist' |
* 'new_blocklist' | 'edit_blocklist' | 'choose_blocklist' | null}
*/
const getTitle = (modalType, whitelist) => {
const titleType = MODAL_TYPE_TO_TITLE_TYPE_MAP[modalType];
if (!titleType) {
return null;
}
return `${titleType}_${whitelist ? 'allowlist' : 'blocklist'}`;
};
const getSelectedValues = (filters, catalogSourcesToIdMap) => filters.reduce((acc, { url }) => {
if (Object.prototype.hasOwnProperty.call(catalogSourcesToIdMap, url)) {
const fieldId = `filter${catalogSourcesToIdMap[url]}`;
acc.selectedFilterIds[fieldId] = true;
acc.selectedSources[url] = true;
}
return acc;
}, {
selectedFilterIds: {},
selectedSources: {},
});
class Modal extends Component {
closeModal = () => {
this.props.toggleModal();
this.props.toggleFilteringModal();
};
render() {
@@ -23,19 +57,30 @@ class Modal extends Component {
modalType,
currentFilterData,
whitelist,
toggleFilteringModal,
filters,
t,
filtersCatalog,
} = this.props;
const newListTitle = whitelist ? (
<Trans>new_allowlist</Trans>
) : (
<Trans>new_blocklist</Trans>
);
let initialValues;
let selectedSources;
switch (modalType) {
case MODAL_TYPE.EDIT_FILTERS:
initialValues = currentFilterData;
break;
case MODAL_TYPE.CHOOSE_FILTERING_LIST: {
const catalogSourcesToIdMap = getMap(Object.values(filtersCatalog.filters), 'source', 'id');
const editListTitle = whitelist ? (
<Trans>edit_allowlist</Trans>
) : (
<Trans>edit_blocklist</Trans>
);
const selectedValues = getSelectedValues(filters, catalogSourcesToIdMap);
initialValues = selectedValues.selectedFilterIds;
selectedSources = selectedValues.selectedSources;
break;
}
default:
}
const title = t(getTitle(modalType, whitelist));
return (
<ReactModal
@@ -46,24 +91,22 @@ class Modal extends Component {
>
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">
{modalType === MODAL_TYPE.EDIT ? (
editListTitle
) : (
newListTitle
)}
</h4>
{title && <h4 className="modal-title">{title}</h4>}
<button type="button" className="close" onClick={this.closeModal}>
<span className="sr-only">Close</span>
</button>
</div>
<Form
initialValues={{ ...currentFilterData }}
selectedSources={selectedSources}
initialValues={initialValues}
filtersCatalog={filtersCatalog}
modalType={modalType}
onSubmit={handleSubmit}
processingAddFilter={processingAddFilter}
processingConfigFilter={processingConfigFilter}
closeModal={this.closeModal}
whitelist={whitelist}
toggleFilteringModal={toggleFilteringModal}
/>
</div>
</ReactModal>
@@ -72,7 +115,7 @@ class Modal extends Component {
}
Modal.propTypes = {
toggleModal: PropTypes.func.isRequired,
toggleFilteringModal: PropTypes.func.isRequired,
isOpen: PropTypes.bool.isRequired,
addFilter: PropTypes.func.isRequired,
isFilterAdded: PropTypes.bool.isRequired,
@@ -83,6 +126,8 @@ Modal.propTypes = {
currentFilterData: PropTypes.object.isRequired,
t: PropTypes.func.isRequired,
whitelist: PropTypes.bool,
filters: PropTypes.array.isRequired,
filtersCatalog: PropTypes.object,
};
export default withTranslation()(Modal);

View File

@@ -3,10 +3,9 @@ import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import {
renderInputField, required, domain, answer,
} from '../../../helpers/form';
import { renderInputField } from '../../../helpers/form';
import { validateAnswer, validateDomain, validateRequiredValue } from '../../../helpers/validators';
import { FORM_NAME } from '../../../helpers/constants';
const Form = (props) => {
const {
@@ -33,7 +32,7 @@ const Form = (props) => {
type="text"
className="form-control"
placeholder={t('form_domain')}
validate={[required, domain]}
validate={[validateRequiredValue, validateDomain]}
/>
</div>
@@ -60,11 +59,18 @@ const Form = (props) => {
type="text"
className="form-control"
placeholder={t('form_answer')}
validate={[required, answer]}
validate={[validateRequiredValue, validateAnswer]}
/>
</div>
</div>
<ul>{['rewrite_ip_address',
'rewrite_domain_name',
'rewrite_A',
'rewrite_AAAA']
.map((str) => <li key={str}>
<Trans components={[<code key="0">text</code>]}>{str}</Trans>
</li>)
}</ul>
<div className="modal-footer">
<div className="btn-list">
<button
@@ -104,7 +110,7 @@ Form.propTypes = {
export default flow([
withTranslation(),
reduxForm({
form: 'rewritesForm',
form: FORM_NAME.REWRITES,
enableReinitialize: true,
}),
])(Form);

View File

@@ -5,7 +5,7 @@ import { withTranslation } from 'react-i18next';
class Table extends Component {
cellWrap = ({ value }) => (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
<span className="logs__text" title={value}>
{value}
</span>
@@ -31,7 +31,7 @@ class Table extends Component {
<div className="logs__row logs__row--center">
<button
type="button"
className="btn btn-icon btn-outline-secondary btn-sm"
className="btn btn-icon btn-icon--green btn-outline-secondary btn-sm"
onClick={() => this.props.handleDelete({
answer: value.row.answer,
domain: value.row.domain,
@@ -59,16 +59,26 @@ class Table extends Component {
columns={this.columns}
loading={processing || processingAdd || processingDelete}
className="-striped -highlight card-table-overflow"
showPagination={true}
showPagination
defaultPageSize={10}
minRows={5}
previousText={t('previous_btn')}
nextText={t('next_btn')}
previousText={
<svg className="icons icon--small icon--gray">
<use xlinkHref="#arrow-left" />
</svg>}
nextText={
<svg className="icons icon--small icon--gray">
<use xlinkHref="#arrow-right" />
</svg>}
loadingText={t('loading_table_status')}
pageText={t('page_table_footer_text')}
ofText="/"
pageText=''
ofText=''
rowsText={t('rows_table_footer_text')}
noDataText={t('rewrite_not_found')}
showPageSizeOptions={false}
showPageJump={false}
renderTotalPagesCount={() => false}
getPaginationProps={() => ({ className: 'custom-pagination' })}
/>
);
}

View File

@@ -6,7 +6,7 @@ import flow from 'lodash/flow';
import { toggleAllServices } from '../../../helpers/helpers';
import { renderServiceField } from '../../../helpers/form';
import { SERVICES } from '../../../helpers/constants';
import { FORM_NAME, SERVICES } from '../../../helpers/constants';
const Form = (props) => {
const {
@@ -84,7 +84,7 @@ Form.propTypes = {
export default flow([
withTranslation(),
reduxForm({
form: 'servicesForm',
form: FORM_NAME.SERVICES,
enableReinitialize: true,
}),
])(Form);

View File

@@ -0,0 +1,64 @@
import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import Form from './Form';
import Card from '../../ui/Card';
import { getBlockedServices, setBlockedServices } from '../../../actions/services';
import PageTitle from '../../ui/PageTitle';
const getInitialDataForServices = (initial) => (initial ? initial.reduce(
(acc, service) => {
acc.blocked_services[service] = true;
return acc;
}, { blocked_services: {} },
) : initial);
const Services = () => {
const [t] = useTranslation();
const dispatch = useDispatch();
const services = useSelector((store) => store?.services);
useEffect(() => {
dispatch(getBlockedServices());
}, []);
const handleSubmit = (values) => {
if (!values || !values.blocked_services) {
return;
}
const blocked_services = Object
.keys(values.blocked_services)
.filter((service) => values.blocked_services[service]);
dispatch(setBlockedServices(blocked_services));
};
const initialValues = getInitialDataForServices(services.list);
return (
<>
<PageTitle
title={t('blocked_services')}
subtitle={t('blocked_services_desc')}
/>
<Card
bodyType="card-body box-body--settings"
>
<div className="form">
<Form
initialValues={initialValues}
processing={services.processing}
processingSet={services.processingSet}
onSubmit={handleSubmit}
/>
</div>
</Card>
</>
);
};
Services.propTypes = {};
export default Services;

View File

@@ -48,7 +48,7 @@ class Table extends Component {
accessor: 'url',
minWidth: 200,
Cell: ({ value }) => (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
{isValidAbsolutePath(value) ? value
: <a
href={value}
@@ -92,7 +92,7 @@ class Table extends Component {
className="btn btn-icon btn-outline-primary btn-sm mr-2"
title={t('edit_table_action')}
onClick={() => toggleFilteringModal({
type: MODAL_TYPE.EDIT,
type: MODAL_TYPE.EDIT_FILTERS,
url: value,
})
}
@@ -126,17 +126,26 @@ class Table extends Component {
<ReactTable
data={filters}
columns={this.columns}
showPagination={true}
showPagination
defaultPageSize={10}
showPageSizeOptions={false}
showPageJump={false}
renderTotalPagesCount={() => false}
loading={loading}
minRows={6}
previousText={t('previous_btn')}
nextText={t('next_btn')}
pageText=''
ofText=''
loadingText={t('loading_table_status')}
pageText={t('page_table_footer_text')}
ofText="/"
rowsText={t('rows_table_footer_text')}
noDataText={whitelist ? t('no_whitelist_added') : t('no_blocklist_added')}
getPaginationProps={() => ({ className: 'custom-pagination' })}
previousText={
<svg className="icons icon--small icon--gray w-100 h-100">
<use xlinkHref="#arrow-left" />
</svg>}
nextText={
<svg className="icons icon--small icon--gray w-100 h-100">
<use xlinkHref="#arrow-right" />
</svg>}
/>
);
}

View File

@@ -160,6 +160,10 @@
display: none;
}
.nav-icon--gray {
color: #9aa0ac;
}
.header-brand-img {
height: 32px;
}

View File

@@ -37,6 +37,7 @@ const FILTERS_ITEMS = [
{ route: FILTERS_URLS.dns_blocklists, text: 'dns_blocklists' },
{ route: FILTERS_URLS.dns_allowlists, text: 'dns_allowlists' },
{ route: FILTERS_URLS.dns_rewrites, text: 'dns_rewrites' },
{ route: FILTERS_URLS.blocked_services, text: 'blocked_services' },
{ route: FILTERS_URLS.custom_rules, text: 'custom_filtering_rules' },
];

View File

@@ -0,0 +1,110 @@
.tooltip__container {
padding: 1rem 1.5rem 1.25rem 1.5rem;
font-size: 16px !important;
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.2);
border-radius: 4px !important;
pointer-events: auto !important;
background-color: var(--white);
z-index: 102;
overflow-y: scroll;
max-height: 100%;
}
.white-space--nowrap {
white-space: nowrap !important;
}
.overflow-break {
white-space: normal !important;
overflow-wrap: break-word;
}
.grid {
display: grid;
grid-template-columns: repeat(2, min-content);
grid-row-gap: 0.5rem;
grid-column-gap: 1rem;
}
.grid--limited {
grid-template-columns: repeat(2, minmax(0, min-content));
}
.grid--gap-bg {
grid-column-gap: 1.5rem;
}
.grid--title {
font-weight: bold;
}
.grid--title:not(:first-child) {
padding-top: 1rem;
}
@media (max-width: 767.98px) {
.grid {
grid-template-columns: 35% 55%;
}
.grid * {
grid-column: 1 / -1;
}
.grid > :nth-child(even) {
margin: -0.5rem 0 0;
}
.grid > .key__time_table_header, .grid > .key__data, .grid > .key__encryption_status, .grid > .key__elapsed {
grid-column: 1 / span 1;
}
.grid > .value__time_table_header, .grid > .value__data, .grid > .value__encryption_status, .grid > .value__elapsed {
grid-column: 2 / span 1;
margin: 0 !important;
}
.grid .key-colon, .grid .title--border {
font-weight: bold;
}
}
.grid .key-colon:nth-child(odd)::after {
content: ':';
}
.grid__one-row {
grid-template-columns: 15rem;
}
.grid__flow-column {
grid-auto-flow: column;
}
.grid-content > * {
justify-content: space-between !important;
width: 100% !important;
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
}
.title--border {
padding-top: 2rem;
}
.title--border:before {
content: '';
position: absolute;
left: 0;
border-top: 0.5px solid var(--gray-d8) !important;
width: 100%;
margin-top: -1rem;
}
.icon-cross {
position: absolute;
right: 0.5rem;
top: 0.5rem;
}

View File

@@ -0,0 +1,102 @@
import React from 'react';
import { nanoid } from 'nanoid';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { formatClientCell } from '../../../helpers/formatClientCell';
import getHintElement from './getHintElement';
import { checkFiltered } from '../../../helpers/helpers';
import { BLOCK_ACTIONS } from '../../../helpers/constants';
const getClientCell = ({
row, t, isDetailed, toggleBlocking, autoClients, processingRules,
}) => {
const {
reason, client, domain, info: { name, whois_info },
} = row.original;
const autoClient = autoClients.find((autoClient) => autoClient.name === client);
const source = autoClient?.source;
const id = nanoid();
const data = {
address: client,
name,
country: whois_info?.country,
city: whois_info?.city,
network: whois_info?.orgname,
source_label: source,
};
const processedData = Object.entries(data);
const isFiltered = checkFiltered(reason);
const nameClass = classNames('w-90 o-hidden d-flex flex-column', {
'mt-2': isDetailed && !name,
'white-space--nowrap': isDetailed,
});
const hintClass = classNames('icons mr-4 icon--small cursor--pointer icon--light-gray', {
'my-3': isDetailed,
});
const renderBlockingButton = (isFiltered, domain) => {
const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
const buttonClass = classNames('logs__action button__action', {
'btn-outline-secondary': isFiltered,
'btn-outline-danger': !isFiltered,
'logs__action--detailed': isDetailed,
});
const onClick = () => toggleBlocking(buttonType, domain);
return (
<div className={buttonClass}>
<button
type="button"
className={`btn btn-sm ${buttonClass}`}
onClick={onClick}
disabled={processingRules}
>
{t(buttonType)}
</button>
</div>
);
};
return (
<div className="logs__row o-hidden h-100">
{processedData && getHintElement({
className: hintClass,
columnClass: 'grid grid--limited',
tooltipClass: 'px-5 pb-5 pt-4 mw-75',
xlinkHref: 'question',
contentItemClass: 'text-truncate key-colon',
title: 'client_details',
content: processedData,
placement: 'bottom',
})}
<div
className={nameClass}>
<div data-tip={true} data-for={id}>{formatClientCell(row, t, isDetailed)}</div>
{isDetailed && name
&& <div className="detailed-info d-none d-sm-block logs__text"
title={name}>{name}</div>}
</div>
{renderBlockingButton(isFiltered, domain)}
</div>
);
};
getClientCell.propTypes = {
row: PropTypes.object.isRequired,
t: PropTypes.func.isRequired,
isDetailed: PropTypes.bool.isRequired,
toggleBlocking: PropTypes.func.isRequired,
autoClients: PropTypes.array.isRequired,
processingRules: PropTypes.bool.isRequired,
};
export default getClientCell;

View File

@@ -0,0 +1,28 @@
import React from 'react';
import { formatTime, formatDateTime } from '../../../helpers/helpers';
import {
DEFAULT_SHORT_DATE_FORMAT_OPTIONS,
DEFAULT_TIME_FORMAT,
} from '../../../helpers/constants';
const getDateCell = (row, isDetailed) => {
const { time } = row.original;
if (!time) {
return '';
}
const formattedTime = formatTime(time, DEFAULT_TIME_FORMAT);
const formattedDate = formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS);
return (
<div className="logs__cell">
<div className="logs__time" title={formattedTime}>{formattedTime}</div>
{isDetailed && <div className="detailed-info d-none d-sm-block text-truncate"
title={formattedDate}>{formattedDate}</div>}
</div>
);
};
export default getDateCell;

View File

@@ -0,0 +1,124 @@
import React from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import getHintElement from './getHintElement';
import {
DEFAULT_SHORT_DATE_FORMAT_OPTIONS,
LONG_TIME_FORMAT,
SCHEME_TO_PROTOCOL_MAP,
} from '../../../helpers/constants';
import { captitalizeWords, formatDateTime, formatTime } from '../../../helpers/helpers';
import { getSourceData } from '../../../helpers/trackers/trackers';
const getDomainCell = (props) => {
const {
row, t, isDetailed, dnssec_enabled,
} = props;
const {
tracker, type, answer_dnssec, client_proto, domain, time,
} = row.original;
const hasTracker = !!tracker;
const lockIconClass = classNames('icons', 'icon--small', 'd-none', 'd-sm-block', 'cursor--pointer', {
'icon--active': answer_dnssec,
'icon--disabled': !answer_dnssec,
'my-3': isDetailed,
});
const privacyIconClass = classNames('icons', 'mx-2', 'icon--small', 'd-none', 'd-sm-block', 'cursor--pointer', {
'icon--active': hasTracker,
'icon--disabled': !hasTracker,
'my-3': isDetailed,
});
const dnssecHint = getHintElement({
className: lockIconClass,
tooltipClass: 'py-4 px-5 pb-45',
canShowTooltip: answer_dnssec,
xlinkHref: 'lock',
columnClass: 'w-100',
content: 'validated_with_dnssec',
placement: 'bottom',
});
const protocol = t(SCHEME_TO_PROTOCOL_MAP[client_proto]) || '';
const ip = type ? `${t('type_table_header')}: ${type}` : '';
const requestDetailsObj = {
time_table_header: formatTime(time, LONG_TIME_FORMAT),
date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS),
domain,
type_table_header: type,
protocol,
};
const sourceData = getSourceData(tracker);
const knownTrackerDataObj = {
name_table_header: tracker?.name,
category_label: hasTracker && captitalizeWords(tracker.category),
source_label: sourceData
&& <a href={sourceData.url} target="_blank" rel="noopener noreferrer"
className="link--green">{sourceData.name}</a>,
};
const renderGrid = (content, idx) => {
const preparedContent = typeof content === 'string' ? t(content) : content;
const className = classNames('text-truncate key-colon o-hidden', {
'overflow-break': preparedContent.length > 100,
});
return <div key={idx} className={className}>{preparedContent}</div>;
};
const getGrid = (contentObj, title, className) => [
<div key={title} className={classNames('pb-2 grid--title', className)}>{t(title)}</div>,
<div key={`${title}-1`}
className="grid grid--limited">{React.Children.map(Object.entries(contentObj), renderGrid)}</div>,
];
const requestDetails = getGrid(requestDetailsObj, 'request_details');
const renderContent = hasTracker ? requestDetails.concat(getGrid(knownTrackerDataObj, 'known_tracker', 'pt-4')) : requestDetails;
const trackerHint = getHintElement({
className: privacyIconClass,
tooltipClass: 'pt-4 pb-5 px-5 mw-75',
xlinkHref: 'privacy',
contentItemClass: 'key-colon',
renderContent,
place: 'bottom',
});
const valueClass = classNames('w-100', {
'px-2 d-flex justify-content-center flex-column': isDetailed,
});
const details = [ip, protocol].filter(Boolean)
.join(', ');
return (
<div className="logs__row o-hidden">
{dnssec_enabled && dnssecHint}
{trackerHint}
<div className={valueClass}>
<div className="text-truncate" title={domain}>{domain}</div>
{details && isDetailed
&& <div className="detailed-info d-none d-sm-block text-truncate"
title={details}>{details}</div>}
</div>
</div>
);
};
getDomainCell.propTypes = {
row: PropTypes.object.isRequired,
t: PropTypes.func.isRequired,
isDetailed: PropTypes.bool.isRequired,
toggleBlocking: PropTypes.func.isRequired,
autoClients: PropTypes.array.isRequired,
dnssec_enabled: PropTypes.bool.isRequired,
};
export default getDomainCell;

View File

@@ -0,0 +1,65 @@
import React from 'react';
import PropTypes from 'prop-types';
import TooltipTrigger from 'react-popper-tooltip';
import { Trans } from 'react-i18next';
import classNames from 'classnames';
import './Tooltip.css';
import 'react-popper-tooltip/dist/styles.css';
import { HIDE_TOOLTIP_DELAY } from '../../../helpers/constants';
const getHintElement = ({
className,
contentItemClass,
columnClass,
canShowTooltip = true,
xlinkHref,
title,
placement,
tooltipClass,
content,
renderContent = React.Children.map(
content,
(item, idx) => <div key={idx} className={contentItemClass}>
<Trans>{item || '—'}</Trans>
</div>,
),
}) => <TooltipTrigger placement={placement} trigger="hover" delayHide={HIDE_TOOLTIP_DELAY} tooltip={
({
tooltipRef,
getTooltipProps,
}) => <div {...getTooltipProps({
ref: tooltipRef,
className: classNames('tooltip__container', tooltipClass, { 'd-none': !canShowTooltip }),
})}
>
{title && <div className="pb-4 h-25 grid-content font-weight-bold">
<Trans>{title}</Trans>
</div>}
<div className={classNames(columnClass)}>{renderContent}</div>
</div>
}>{({
getTriggerProps, triggerRef,
}) => <span {...getTriggerProps({ ref: triggerRef })}>
{xlinkHref && <svg className={className}>
<use xlinkHref={`#${xlinkHref}`} />
</svg>}
</span>}
</TooltipTrigger>;
getHintElement.propTypes = {
className: PropTypes.string,
contentItemClass: PropTypes.string,
columnClass: PropTypes.string,
tooltipClass: PropTypes.string,
title: PropTypes.string,
placement: PropTypes.string,
canShowTooltip: PropTypes.string,
xlinkHref: PropTypes.string,
content: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
]),
renderContent: PropTypes.arrayOf(PropTypes.element),
};
export default getHintElement;

View File

@@ -0,0 +1,116 @@
import React from 'react';
import classNames from 'classnames';
import { formatElapsedMs } from '../../../helpers/helpers';
import {
FILTERED_STATUS,
FILTERED_STATUS_TO_META_MAP,
} from '../../../helpers/constants';
import getHintElement from './getHintElement';
const getResponseCell = (row, filtering, t, isDetailed, getFilterName) => {
const {
reason, filterId, rule, status, upstream, elapsedMs, domain, response,
} = row.original;
const { filters, whitelistFilters } = filtering;
const formattedElapsedMs = formatElapsedMs(elapsedMs, t);
const statusLabel = t(FILTERED_STATUS_TO_META_MAP[reason]?.label || reason);
const boldStatusLabel = <span className="font-weight-bold">{statusLabel}</span>;
const filter = getFilterName(filters, whitelistFilters, filterId, t);
const renderResponses = (responseArr) => {
if (responseArr.length === 0) {
return '';
}
return <div>{responseArr.map((response) => {
const className = classNames('white-space--nowrap', {
'overflow-break': response.length > 100,
});
return <div key={response} className={className}>{`${response}\n`}</div>;
})}</div>;
};
const FILTERED_STATUS_TO_FIELDS_MAP = {
[FILTERED_STATUS.NOT_FILTERED_NOT_FOUND]: {
domain,
encryption_status: boldStatusLabel,
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
response_code: status,
response_table_header: renderResponses(response),
},
[FILTERED_STATUS.FILTERED_BLOCKED_SERVICE]: {
domain,
encryption_status: boldStatusLabel,
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
filter,
rule_label: rule,
response_code: status,
},
[FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: {
domain,
encryption_status: boldStatusLabel,
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
filter,
rule_label: rule,
response_code: status,
},
[FILTERED_STATUS.NOT_FILTERED_WHITE_LIST]: {
domain,
encryption_status: boldStatusLabel,
filter,
rule_label: rule,
response_code: status,
},
[FILTERED_STATUS.FILTERED_SAFE_SEARCH]: {
domain,
encryption_status: boldStatusLabel,
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
response_code: status,
},
[FILTERED_STATUS.FILTERED_BLACK_LIST]: {
domain,
encryption_status: boldStatusLabel,
filter,
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
response_code: status,
},
};
const fields = FILTERED_STATUS_TO_FIELDS_MAP[reason]
? Object.entries(FILTERED_STATUS_TO_FIELDS_MAP[reason])
: Object.entries(FILTERED_STATUS_TO_FIELDS_MAP.NotFilteredNotFound);
const detailedInfo = reason === FILTERED_STATUS.FILTERED_BLOCKED_SERVICE
|| reason === FILTERED_STATUS.FILTERED_BLACK_LIST
? filter : formattedElapsedMs;
return (
<div className="logs__row">
{fields && getHintElement({
className: classNames('icons mr-4 icon--small cursor--pointer icon--light-gray', { 'my-3': isDetailed }),
columnClass: 'grid grid--limited',
tooltipClass: 'px-5 pb-5 pt-4 mw-75 custom-tooltip__response-details',
contentItemClass: 'text-truncate key-colon o-hidden',
xlinkHref: 'question',
title: 'response_details',
content: fields,
placement: 'bottom',
})}
<div className="text-truncate">
<div className="text-truncate" title={statusLabel}>{statusLabel}</div>
{isDetailed && <div
className="detailed-info d-none d-sm-block pt-1 text-truncate" title={detailedInfo}>{detailedInfo}</div>}
</div>
</div>
);
};
export default getResponseCell;

View File

@@ -0,0 +1,30 @@
import React, { Fragment } from 'react';
import { Trans } from 'react-i18next';
import { HashLink as Link } from 'react-router-hash-link';
import Card from '../ui/Card';
const Disabled = () => (
<Fragment>
<div className="page-header">
<h1 className="page-title page-title--large">
<Trans>query_log</Trans>
</h1>
</div>
<Card>
<div className="lead text-center py-6">
<Trans
components={[
<Link to="/settings#logs-config" key="0">
link
</Link>,
]}
>
query_log_disabled
</Trans>
</div>
</Card>
</Fragment>
);
export default Disabled;

View File

@@ -1,12 +1,18 @@
import React, { Fragment } from 'react';
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import { withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { renderInputField } from '../../../helpers/form';
import { RESPONSE_FILTER } from '../../../helpers/constants';
import { useTranslation } from 'react-i18next';
import debounce from 'lodash/debounce';
import { useDispatch } from 'react-redux';
import classNames from 'classnames';
import {
DEBOUNCE_FILTER_TIMEOUT,
DEFAULT_LOGS_FILTER,
FORM_NAME,
RESPONSE_FILTER,
} from '../../../helpers/constants';
import Tooltip from '../../ui/Tooltip';
import { setLogsFilter } from '../../../actions/queryLogs';
const renderFilterField = ({
input,
@@ -18,29 +24,40 @@ const renderFilterField = ({
autoComplete,
tooltip,
meta: { touched, error },
}) => <Fragment>
<div className="logs__input-wrap">
<input
{...input}
id={id}
placeholder={placeholder}
type={type}
className={className}
disabled={disabled}
autoComplete={autoComplete}
/>
<span className="logs__notice">
<Tooltip text={tooltip} type='tooltip-custom--logs' />
</span>
{!disabled
&& touched
&& (error && <span className="form__message form__message--error">{error}</span>)}
onClearInputClick,
}) => <>
<div className="input-group-search input-group-search__icon--magnifier">
<svg className="icons icon--small icon--gray">
<use xlinkHref="#magnifier" />
</svg>
</div>
</Fragment>;
<input
{...input}
id={id}
placeholder={placeholder}
type={type}
className={className}
disabled={disabled}
autoComplete={autoComplete}
aria-label={placeholder} />
<div
className={classNames('input-group-search input-group-search__icon--cross', { invisible: input.value.length < 1 })}>
<svg className="icons icon--smallest icon--gray" onClick={onClearInputClick}>
<use xlinkHref="#cross" />
</svg>
</div>
<span className="input-group-search input-group-search__icon--tooltip">
<Tooltip text={tooltip} type='tooltip-custom--logs' />
</span>
{!disabled
&& touched
&& (error && <span className="form__message form__message--error">{error}</span>)}
</>;
renderFilterField.propTypes = {
input: PropTypes.object.isRequired,
id: PropTypes.string.isRequired,
onClearInputClick: PropTypes.func.isRequired,
className: PropTypes.string,
placeholder: PropTypes.string,
type: PropTypes.string,
@@ -55,62 +72,64 @@ renderFilterField.propTypes = {
const Form = (props) => {
const {
t,
handleChange,
className = '',
responseStatusClass,
submit,
reset,
setIsLoading,
} = props;
const { t } = useTranslation();
const dispatch = useDispatch();
const debouncedSubmit = debounce(submit, DEBOUNCE_FILTER_TIMEOUT);
const zeroDelaySubmit = () => setTimeout(submit, 0);
const clearInput = async () => {
await dispatch(setLogsFilter(DEFAULT_LOGS_FILTER));
await reset();
};
const onInputClear = async () => {
setIsLoading(true);
await clearInput();
setIsLoading(false);
};
useEffect(() => clearInput, []);
return (
<form onSubmit={handleChange}>
<div className="row">
<div className="col-6 col-sm-3 my-2">
<Field
id="filter_domain"
name="filter_domain"
component={renderFilterField}
type="text"
className="form-control"
placeholder={t('domain_name_table_header')}
tooltip={t('query_log_strict_search')}
onChange={handleChange}
/>
</div>
<div className="col-6 col-sm-3 my-2">
<Field
id="filter_question_type"
name="filter_question_type"
component={renderInputField}
type="text"
className="form-control"
placeholder={t('type_table_header')}
onChange={handleChange}
/>
</div>
<div className="col-6 col-sm-3 my-2">
<Field
name="filter_response_status"
component="select"
className="form-control custom-select"
>
<option value={RESPONSE_FILTER.ALL}>
{t('show_all_filter_type')}
</option>
<option value={RESPONSE_FILTER.FILTERED}>
{t('show_filtered_type')}
</option>
</Field>
</div>
<div className="col-6 col-sm-3 my-2">
<Field
id="filter_client"
name="filter_client"
component={renderFilterField}
type="text"
className="form-control"
placeholder={t('client_table_header')}
tooltip={t('query_log_strict_search')}
onChange={handleChange}
/>
</div>
<form className="d-flex flex-wrap form-control--container"
onSubmit={(e) => {
e.preventDefault();
zeroDelaySubmit();
debouncedSubmit.cancel();
}}
>
<Field
id="search"
name="search"
component={renderFilterField}
type="text"
className={classNames('form-control--search form-control--transparent', className)}
placeholder={t('domain_or_client')}
tooltip={t('query_log_strict_search')}
onChange={debouncedSubmit}
onClearInputClick={onInputClear}
/>
<div className="field__select">
<Field
name="response_status"
component="select"
className={classNames('form-control custom-select custom-select--logs custom-select__arrow--left ml-small form-control--transparent', responseStatusClass)}
onChange={zeroDelaySubmit}
>
{Object.values(RESPONSE_FILTER)
.map(({
query, label, disabled,
}) => <option key={label} value={query}
disabled={disabled}>{t(label)}</option>)}
</Field>
</div>
</form>
);
@@ -118,12 +137,13 @@ const Form = (props) => {
Form.propTypes = {
handleChange: PropTypes.func,
t: PropTypes.func.isRequired,
className: PropTypes.string,
responseStatusClass: PropTypes.string,
submit: PropTypes.func.isRequired,
reset: PropTypes.func.isRequired,
setIsLoading: PropTypes.func.isRequired,
};
export default flow([
withTranslation(),
reduxForm({
form: 'logsFilterForm',
}),
])(Form);
export default reduxForm({
form: FORM_NAME.LOGS_FILTER,
})(Form);

View File

@@ -1,52 +1,49 @@
import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import debounce from 'lodash/debounce';
import classnames from 'classnames';
import { DEBOUNCE_FILTER_TIMEOUT, RESPONSE_FILTER } from '../../../helpers/constants';
import { isValidQuestionType } from '../../../helpers/helpers';
import { Trans } from 'react-i18next';
import { useDispatch } from 'react-redux';
import Form from './Form';
import Card from '../../ui/Card';
import { setLogsFilter } from '../../../actions/queryLogs';
class Filters extends Component {
getFilters = ({
filter_domain, filter_question_type, filter_response_status, filter_client,
}) => ({
filter_domain: filter_domain || '',
filter_question_type: isValidQuestionType(filter_question_type) ? filter_question_type.toUpperCase() : '',
filter_response_status: filter_response_status === RESPONSE_FILTER.FILTERED ? filter_response_status : '',
filter_client: filter_client || '',
});
const Filters = ({ filter, refreshLogs, setIsLoading }) => {
const dispatch = useDispatch();
handleFormChange = debounce((values) => {
const filter = this.getFilters(values);
this.props.setLogsFilter(filter);
}, DEBOUNCE_FILTER_TIMEOUT);
const onSubmit = async (values) => {
setIsLoading(true);
await dispatch(setLogsFilter(values));
setIsLoading(false);
};
render() {
const { filter, processingAdditionalLogs } = this.props;
return (
<div className="page-header page-header--logs">
<h1 className="page-title page-title--large">
<Trans>query_log</Trans>
<button
type="button"
className="btn btn-icon--green ml-3 bg-transparent"
onClick={refreshLogs}
>
<svg className="icons icon--small">
<use xlinkHref="#update" />
</svg>
</button>
const cardBodyClass = classnames({
'card-body': true,
'card-body--loading': processingAdditionalLogs,
});
return (
<Card bodyType={cardBodyClass}>
<Form
initialValues={filter}
onChange={this.handleFormChange}
/>
</Card>
);
}
}
</h1>
<Form
responseStatusClass="d-sm-block"
initialValues={filter}
onSubmit={onSubmit}
setIsLoading={setIsLoading}
/>
</div>
);
};
Filters.propTypes = {
filter: PropTypes.object.isRequired,
setLogsFilter: PropTypes.func.isRequired,
refreshLogs: PropTypes.func.isRequired,
processingGetLogs: PropTypes.bool.isRequired,
processingAdditionalLogs: PropTypes.bool.isRequired,
setIsLoading: PropTypes.func.isRequired,
};
export default Filters;

View File

@@ -1,8 +1,19 @@
:root {
--gray-4d: #4D4D4D;
--gray-8: #888;
--danger: #DF3812;
}
.logs__row {
position: relative;
display: flex;
align-items: center;
min-height: 26px;
overflow: hidden;
text-overflow: ellipsis;
}
.card-table .logs__row {
overflow: visible;
}
.logs__row--center {
@@ -15,10 +26,6 @@
justify-content: center;
}
.logs__row--overflow {
overflow: hidden;
}
.logs__row--icons {
max-width: 180px;
flex-flow: row wrap;
@@ -35,6 +42,15 @@
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
font-size: 1rem;
font-family: var(--font-family-sans-serif);
color: var(--gray-4d);
letter-spacing: 0;
line-height: 1.5rem;
}
.logs__text--bold {
font-weight: bold;
}
.logs__text--full {
@@ -51,6 +67,11 @@
white-space: normal;
}
.logs__text--nowrap {
line-height: 1.4;
white-space: nowrap;
}
.logs__text--whois {
line-height: 1.2;
}
@@ -61,11 +82,18 @@
margin-right: 5px;
}
.logs__action,
.table__action {
position: absolute;
top: 11px;
right: 15px;
.tooltip__option {
height: 2.5rem !important;
width: 10.5rem;
padding: 0.3125rem 1.5rem 0.6875rem;
}
.tooltip__option:hover {
background-color: var(--gray-f3);
cursor: pointer;
}
.button__action {
background-color: #fff;
border-radius: 4px;
transition: opacity 0.2s ease, visibility 0.2s ease;
@@ -73,11 +101,31 @@
opacity: 0;
}
.table__action {
position: absolute;
top: 11px;
right: 15px;
}
.logs__action {
position: absolute;
top: 0;
right: 1rem;
}
.logs__action--detailed {
top: 5px;
}
.logs__table .rt-td,
.clients__table .rt-td {
position: relative;
}
.logs__table .rt-thead, .logs__table .rt-tbody {
min-width: 100% !important;
}
.logs__table .rt-tr:hover .logs__action,
.clients__table .rt-tr:hover .table__action {
visibility: visible;
@@ -151,17 +199,6 @@
position: relative;
}
.logs__notice {
position: absolute;
z-index: 1;
top: 8px;
right: 10px;
margin-top: 3px;
font-size: 12px;
text-align: left;
color: #a5a5a5;
}
.logs__whois {
display: inline;
font-size: 12px;
@@ -185,3 +222,343 @@
margin-right: 1px;
opacity: 0.5;
}
/* New logs */
.logs__table {
background-color: #fff;
border: 0;
border-radius: 8px;
min-height: 42rem;
max-width: 100%;
}
.logs__table--detailed {
min-height: 50rem;
}
.logs__table .rt-thead.-header {
box-shadow: none;
font-weight: bold;
}
.logs__table .rt-thead .rt-th {
padding: 0.9375rem 0.9375rem 0.875rem 0;
text-align: left;
border-right: 0;
}
.logs__table .rt-tbody .rt-td {
padding: 1rem 1rem 0.5rem 0;
border-right: 0;
}
.logs__table .rt-thead .rt-th:last-child,
.logs__table .rt-tbody .rt-td:last-child {
padding-right: 0;
}
.logs__table .rt-tbody .rt-tr-group {
border-bottom: 0;
}
.logs__table .rt-tr {
position: relative;
padding: 0 24px;
}
.logs__table .rt-tr {
position: relative;
padding: 0 1.5rem;
}
.logs__table .rt-tr-group:not(:first-child) .rt-tr:before {
content: "";
position: absolute;
left: 1.5rem;
right: 1.5rem;
top: 0;
width: calc(100% - 3rem);
height: 2px;
background-color: rgba(216, 216, 216, 0.23);
}
.logs__table .rt-tr-group:last-child .rt-tr:after,
.logs__table .rt-thead .rt-tr:after {
display: none;
}
.logs__time {
font-size: 1rem;
line-height: 1.5;
}
.detailed-info {
font-size: 0.8rem;
line-height: 1.4;
color: #888888;
}
.icon--selected {
background-color: var(--gray-f3);
border: solid 1px var(--gray-d8);
border-radius: 4px;
}
/* Hide 3 and 4 column on mobile */
.logs__table .rt-thead .rt-th:nth-child(3),
.logs__table .rt-thead .rt-th:nth-child(4),
.logs__table .rt-tbody .rt-td:nth-child(3),
.logs__table .rt-tbody .rt-td:nth-child(4) {
display: none;
}
@media screen and (min-width: 768px) {
.logs__table .rt-thead .rt-th:nth-child(3),
.logs__table .rt-thead .rt-th:nth-child(4),
.logs__table .rt-tbody .rt-td:nth-child(3),
.logs__table .rt-tbody .rt-td:nth-child(4) {
display: block;
}
}
.text-pre {
white-space: pre-wrap !important;
overflow-wrap: break-word;
overflow: visible;
}
.custom-pagination {
width: 11.875rem !important;
background-color: transparent;
box-shadow: none !important;
border: none !important;
align-items: center !important;
}
.custom-pagination--padding {
padding: 2.5rem 0 2.5rem !important;
}
.custom-pagination .-btn {
--side-size: 2rem;
background-color: transparent !important;
border: 1px solid var(--gray-d8) !important;
border-radius: 4px !important;
width: var(--side-size) !important;
height: var(--side-size) !important;
}
.custom-pagination .-btn:enabled:hover {
background-color: var(--gray-f3) !important;
}
.custom-pagination .-previous {
flex: 0 1 !important;
}
.custom-pagination .-next {
flex: 0 1 !important;
}
.custom-pagination .-btn {
display: flex !important;
}
.-pageInfo {
--side-size: 2rem;
font-variant-numeric: tabular-nums !important;
background-color: transparent !important;
border: 1px solid var(--gray-d8) !important;
border-radius: 4px !important;
width: var(--side-size) !important;
height: var(--side-size) !important;
margin: 0 !important;
display: flex !important;
justify-content: center;
align-items: center;
}
.pagination-bottom {
justify-content: center !important;
display: flex !important;
}
.-center:before {
content: '...';
transform: translateY(-0.25rem);
margin: auto;
}
.-center:after {
content: '...';
transform: translateY(-0.25rem);
margin: auto;
}
.icon--detailed-info {
position: absolute;
right: 0;
top: 0.5rem;
}
.icon--light-gray {
color: var(--gray-8);
}
.link--green {
color: var(--green79);
}
.row--detailed {
height: 4.9rem
}
.w-90 {
max-width: 90% !important;
}
.h-85 {
height: 85% !important;
}
.pt-45 {
padding-top: 1.25rem !important;
}
.pb-45 {
padding-bottom: 1.25rem !important;
}
.py-45 {
padding-top: 1.25rem !important;
padding-bottom: 1.25rem !important;
}
.mh-100 {
max-height: 100% !important;
}
.cursor--pointer {
cursor: pointer;
}
.custom-select__arrow--left {
background: #fff url('./chevron-down.svg') no-repeat left 0.2rem center;
background-size: 1.5rem;
}
.custom-select--logs {
padding: 0.5rem 0.75rem 0.5rem 1.75rem !important;
}
.bg--danger {
color: var(--danger);
}
.ml-small {
margin-left: 3.3125rem;
}
.form-control--search {
width: 39.125rem;
box-shadow: 0 1px 0 #ddd;
padding: 0 2.5rem;
height: 2.25rem;
}
.form-control--transparent {
border: 0 solid transparent !important;
background-color: transparent !important;
}
.input-group-search {
background-color: transparent;
position: relative;
width: 1.5rem;
height: 1.5rem;
top: 0.4rem;
}
.input-group-search__icon--magnifier {
left: 2rem;
}
.input-group-search__icon--cross {
left: -4.5rem;
cursor: pointer;
}
.input-group-search__icon--tooltip {
left: -4rem;
}
.form-control--container {
max-width: 100%;
}
@media (max-width: 1279.98px) {
.form-control--search {
max-width: 30.125rem;
}
.form-control--container {
max-width: 70%;
}
.form-control--search {
max-width: 50%;
}
}
@media (max-width: 991.98px) {
.form-control--search {
max-width: 40%;
}
.form-control--container {
max-width: 100%;
}
}
@media (max-width: 767.98px) {
.rt-tr .logs__row .logs__text {
max-width: calc(100% - 1.5rem);
}
.ml-small {
margin-left: 1.5rem;
}
}
@media (max-width: 575px) {
.logs__table .rt-tr {
height: 3.125rem;
}
.logs__table .rt-tbody .rt-td {
padding: 0.625rem 1rem 0.875rem 0;
}
.logs__table {
min-height: 42rem;
}
}
@media (max-width: 500px) {
.form-control--search {
max-width: 85%;
}
.field__select {
margin-top: 1.5rem;
}
}
.loading__container > .-loading-inner {
top: 10rem !important;
bottom: initial !important;
}
.loading__text {
transform: translateY(3rem);
}

View File

@@ -0,0 +1,426 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useTranslation, Trans } from 'react-i18next';
import ReactTable from 'react-table';
import classNames from 'classnames';
import endsWith from 'lodash/endsWith';
import escapeRegExp from 'lodash/escapeRegExp';
import {
BLOCK_ACTIONS,
DEFAULT_SHORT_DATE_FORMAT_OPTIONS,
LONG_TIME_FORMAT,
FILTERED_STATUS_TO_META_MAP,
TABLE_DEFAULT_PAGE_SIZE,
SCHEME_TO_PROTOCOL_MAP,
CUSTOM_FILTERING_RULES_ID,
} from '../../helpers/constants';
import getDateCell from './Cells/getDateCell';
import getDomainCell from './Cells/getDomainCell';
import getClientCell from './Cells/getClientCell';
import getResponseCell from './Cells/getResponseCell';
import {
captitalizeWords,
checkFiltered,
formatDateTime,
formatElapsedMs,
formatTime,
} from '../../helpers/helpers';
import Loading from '../ui/Loading';
import { getSourceData } from '../../helpers/trackers/trackers';
const Table = (props) => {
const {
setDetailedDataCurrent,
setButtonType,
setModalOpened,
isSmallScreen,
setIsLoading,
filtering,
isDetailed,
toggleDetailedLogs,
setLogsPage,
setLogsPagination,
processingGetLogs,
logs,
pages,
page,
isLoading,
} = props;
const [t] = useTranslation();
const toggleBlocking = (type, domain) => {
const {
setRules, getFilteringStatus, addSuccessToast,
} = props;
const { userRules } = filtering;
const lineEnding = !endsWith(userRules, '\n') ? '\n' : '';
const baseRule = `||${domain}^$important`;
const baseUnblocking = `@@${baseRule}`;
const blockingRule = type === BLOCK_ACTIONS.BLOCK ? baseUnblocking : baseRule;
const unblockingRule = type === BLOCK_ACTIONS.BLOCK ? baseRule : baseUnblocking;
const preparedBlockingRule = new RegExp(`(^|\n)${escapeRegExp(blockingRule)}($|\n)`);
const preparedUnblockingRule = new RegExp(`(^|\n)${escapeRegExp(unblockingRule)}($|\n)`);
const matchPreparedBlockingRule = userRules.match(preparedBlockingRule);
const matchPreparedUnblockingRule = userRules.match(preparedUnblockingRule);
if (matchPreparedBlockingRule) {
setRules(userRules.replace(`${blockingRule}`, ''));
addSuccessToast(`${t('rule_removed_from_custom_filtering_toast')}: ${blockingRule}`);
} else if (!matchPreparedUnblockingRule) {
setRules(`${userRules}${lineEnding}${unblockingRule}\n`);
addSuccessToast(`${t('rule_added_to_custom_filtering_toast')}: ${unblockingRule}`);
} else if (matchPreparedUnblockingRule) {
addSuccessToast(`${t('rule_added_to_custom_filtering_toast')}: ${unblockingRule}`);
return;
} else if (!matchPreparedBlockingRule) {
addSuccessToast(`${t('rule_removed_from_custom_filtering_toast')}: ${blockingRule}`);
return;
}
getFilteringStatus();
};
const getFilterName = (filters, whitelistFilters, filterId, t) => {
if (filterId === CUSTOM_FILTERING_RULES_ID) {
return t('custom_filter_rules');
}
const filter = filters.find((filter) => filter.id === filterId)
|| whitelistFilters.find((filter) => filter.id === filterId);
let filterName = '';
if (filter) {
filterName = filter.name;
}
if (!filterName) {
filterName = t('unknown_filter', { filterId });
}
return filterName;
};
const columns = [
{
Header: t('time_table_header'),
accessor: 'time',
Cell: (row) => getDateCell(row, isDetailed),
minWidth: 70,
maxHeight: 60,
headerClassName: 'logs__text',
},
{
Header: t('request_table_header'),
accessor: 'domain',
Cell: (row) => {
const {
isDetailed,
autoClients,
dnssec_enabled,
} = props;
return getDomainCell({
row,
t,
isDetailed,
toggleBlocking,
autoClients,
dnssec_enabled,
});
},
minWidth: 180,
maxHeight: 60,
headerClassName: 'logs__text',
},
{
Header: t('response_table_header'),
accessor: 'response',
Cell: (row) => getResponseCell(
row,
filtering,
t,
isDetailed,
getFilterName,
),
minWidth: 150,
maxHeight: 60,
headerClassName: 'logs__text',
},
{
Header: () => {
const plainSelected = classNames('cursor--pointer', {
'icon--selected': !isDetailed,
});
const detailedSelected = classNames('cursor--pointer', {
'icon--selected': isDetailed,
});
return <div className="d-flex justify-content-between">
{t('client_table_header')}
{<span>
<svg
className={`icons icon--small icon--active mr-2 cursor--pointer ${plainSelected}`}
onClick={() => toggleDetailedLogs(false)}
>
<title><Trans>compact</Trans></title>
<use xlinkHref='#list' />
</svg>
<svg
className={`icons icon--small icon--active cursor--pointer ${detailedSelected}`}
onClick={() => toggleDetailedLogs(true)}
>
<title><Trans>default</Trans></title>
<use xlinkHref='#detailed_list' />
</svg>
</span>}
</div>;
},
accessor: 'client',
Cell: (row) => {
const {
isDetailed,
autoClients,
filtering: { processingRules },
} = props;
return getClientCell({
row,
t,
isDetailed,
toggleBlocking,
autoClients,
processingRules,
});
},
minWidth: 123,
maxHeight: 60,
headerClassName: 'logs__text',
className: 'pb-0',
},
];
const changePage = async (page) => {
setIsLoading(true);
const { oldest, getLogs, pages } = props;
const isLastPage = pages && (page + 1 === pages);
await Promise.all([
setLogsPage(page),
setLogsPagination({
page,
pageSize: TABLE_DEFAULT_PAGE_SIZE,
}),
].concat(isLastPage ? getLogs(oldest, page) : []));
setIsLoading(false);
};
const tableClass = classNames('logs__table', {
'logs__table--detailed': isDetailed,
});
return (
<ReactTable
manual
minRows={0}
page={page}
pages={pages}
columns={columns}
filterable={false}
sortable={false}
resizable={false}
data={logs || []}
loading={isLoading}
showPageJump={false}
showPageSizeOptions={false}
onPageChange={changePage}
className={tableClass}
defaultPageSize={TABLE_DEFAULT_PAGE_SIZE}
loadingText={
<>
<Loading />
<h6 className="loading__text">{t('loading_table_status')}</h6>
</>
}
getLoadingProps={() => ({ className: 'loading__container' })}
rowsText={t('rows_table_footer_text')}
noDataText={!processingGetLogs
&& <label className="logs__text logs__text--bold">{t('nothing_found')}</label>}
pageText=''
ofText=''
showPagination={logs.length > 0}
getPaginationProps={() => ({ className: 'custom-pagination custom-pagination--padding' })}
getTbodyProps={() => ({ className: 'd-block' })}
previousText={
<svg className="icons icon--small icon--gray w-100 h-100 cursor--pointer">
<title><Trans>previous_btn</Trans></title>
<use xlinkHref="#arrow-left" />
</svg>}
nextText={
<svg className="icons icon--small icon--gray w-100 h-100 cursor--pointer">
<title><Trans>next_btn</Trans></title>
<use xlinkHref="#arrow-right" />
</svg>}
renderTotalPagesCount={() => false}
getTrGroupProps={(_state, rowInfo) => {
if (!rowInfo) {
return {};
}
const { reason } = rowInfo.original;
const colorClass = FILTERED_STATUS_TO_META_MAP[reason] ? FILTERED_STATUS_TO_META_MAP[reason].color : 'white';
return { className: colorClass };
}}
getTrProps={(state, rowInfo) => ({
className: isDetailed ? 'row--detailed' : '',
onClick: () => {
if (isSmallScreen) {
const { dnssec_enabled, autoClients } = props;
const {
answer_dnssec,
client,
domain,
elapsedMs,
info,
reason,
response,
time,
tracker,
upstream,
type,
client_proto,
filterId,
} = rowInfo.original;
const hasTracker = !!tracker;
const autoClient = autoClients
.find((autoClient) => autoClient.name === client);
const { whois_info } = info;
const country = whois_info?.country;
const city = whois_info?.city;
const network = whois_info?.orgname;
const source = autoClient?.source;
const formattedElapsedMs = formatElapsedMs(elapsedMs, t);
const isFiltered = checkFiltered(reason);
const buttonType = isFiltered ? BLOCK_ACTIONS.UNBLOCK : BLOCK_ACTIONS.BLOCK;
const onToggleBlock = () => {
toggleBlocking(buttonType, domain);
};
const status = t(FILTERED_STATUS_TO_META_MAP[reason]?.label || reason);
const statusBlocked = <div className="bg--danger">{status}</div>;
const protocol = t(SCHEME_TO_PROTOCOL_MAP[client_proto]) || '';
const sourceData = getSourceData(tracker);
const detailedData = {
time_table_header: formatTime(time, LONG_TIME_FORMAT),
date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS),
encryption_status: status,
domain,
type_table_header: type,
protocol,
known_tracker: hasTracker && 'title',
table_name: tracker?.name,
category_label: hasTracker && captitalizeWords(tracker.category),
tracker_source: hasTracker && sourceData
&& <a href={sourceData.url} target="_blank" rel="noopener noreferrer"
className="link--green">{sourceData.name}</a>,
response_details: 'title',
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
response_table_header: response?.join('\n'),
client_details: 'title',
ip_address: client,
name: info?.name,
country,
city,
network,
source_label: source,
validated_with_dnssec: dnssec_enabled ? Boolean(answer_dnssec) : false,
[buttonType]: <div onClick={onToggleBlock}
className="title--border bg--danger text-center">{t(buttonType)}</div>,
};
const { filters, whitelistFilters } = filtering;
const filter = getFilterName(filters, whitelistFilters, filterId, t);
const detailedDataBlocked = {
time_table_header: formatTime(time, LONG_TIME_FORMAT),
date: formatDateTime(time, DEFAULT_SHORT_DATE_FORMAT_OPTIONS),
encryption_status: statusBlocked,
domain,
type_table_header: type,
protocol,
known_tracker: 'title',
table_name: tracker?.name,
category_label: hasTracker && captitalizeWords(tracker.category),
source_label: hasTracker && sourceData
&& <a href={sourceData.url} target="_blank" rel="noopener noreferrer"
className="link--green">{sourceData.name}</a>,
response_details: 'title',
install_settings_dns: upstream,
elapsed: formattedElapsedMs,
filter,
response_table_header: response?.join('\n'),
[buttonType]: <div onClick={onToggleBlock}
className="title--border text-center">{t(buttonType)}</div>,
};
const detailedDataCurrent = isFiltered ? detailedDataBlocked : detailedData;
setDetailedDataCurrent(detailedDataCurrent);
setButtonType(buttonType);
setModalOpened(true);
}
},
})}
/>
);
};
Table.propTypes = {
logs: PropTypes.array.isRequired,
pages: PropTypes.number.isRequired,
page: PropTypes.number.isRequired,
autoClients: PropTypes.array.isRequired,
defaultPageSize: PropTypes.number,
oldest: PropTypes.string.isRequired,
filtering: PropTypes.object.isRequired,
processingGetLogs: PropTypes.bool.isRequired,
processingGetConfig: PropTypes.bool.isRequired,
isDetailed: PropTypes.bool.isRequired,
setLogsPage: PropTypes.func.isRequired,
setLogsPagination: PropTypes.func.isRequired,
getLogs: PropTypes.func.isRequired,
toggleDetailedLogs: PropTypes.func.isRequired,
setRules: PropTypes.func.isRequired,
addSuccessToast: PropTypes.func.isRequired,
getFilteringStatus: PropTypes.func.isRequired,
isLoading: PropTypes.bool.isRequired,
setIsLoading: PropTypes.func.isRequired,
dnssec_enabled: PropTypes.bool.isRequired,
setDetailedDataCurrent: PropTypes.func.isRequired,
setButtonType: PropTypes.func.isRequired,
setModalOpened: PropTypes.func.isRequired,
isSmallScreen: PropTypes.bool.isRequired,
};
export default Table;

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#9aa0ac" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-down"><polyline points="6 9 12 15 18 9"></polyline></svg>

After

Width:  |  Height:  |  Size: 264 B

View File

@@ -1,457 +1,210 @@
import React, { Component, Fragment } from 'react';
import React, { Fragment, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import ReactTable from 'react-table';
import escapeRegExp from 'lodash/escapeRegExp';
import endsWith from 'lodash/endsWith';
import { Trans, withTranslation } from 'react-i18next';
import { HashLink as Link } from 'react-router-hash-link';
import { Trans } from 'react-i18next';
import Modal from 'react-modal';
import { useDispatch } from 'react-redux';
import {
formatTime,
formatDateTime,
isToday,
checkFiltered,
checkRewrite,
checkRewriteHosts,
checkWhiteList,
checkBlackList,
checkBlockedService,
} from '../../helpers/helpers';
import {
SERVICES, TABLE_DEFAULT_PAGE_SIZE, CUSTOM_FILTERING_RULES_ID, FILTERED,
BLOCK_ACTIONS, smallScreenSize,
TABLE_DEFAULT_PAGE_SIZE,
TABLE_FIRST_PAGE,
} from '../../helpers/constants';
import { getTrackerData } from '../../helpers/trackers/trackers';
import { formatClientCell } from '../../helpers/formatClientCell';
import Filters from './Filters';
import PageTitle from '../ui/PageTitle';
import Card from '../ui/Card';
import Loading from '../ui/Loading';
import PopoverFiltered from '../ui/PopoverFilter';
import Popover from '../ui/Popover';
import Filters from './Filters';
import Table from './Table';
import Disabled from './Disabled';
import { getFilteringStatus } from '../../actions/filtering';
import { getClients } from '../../actions';
import { getDnsConfig } from '../../actions/dnsConfig';
import { getLogsConfig } from '../../actions/queryLogs';
import { addSuccessToast } from '../../actions/toasts';
import './Logs.css';
import CellWrap from '../ui/CellWrap';
const TABLE_FIRST_PAGE = 0;
const INITIAL_REQUEST = true;
const INITIAL_REQUEST_DATA = ['', TABLE_FIRST_PAGE, INITIAL_REQUEST];
class Logs extends Component {
componentDidMount() {
this.props.setLogsPage(TABLE_FIRST_PAGE);
this.getLogs(...INITIAL_REQUEST_DATA);
this.props.getFilteringStatus();
this.props.getLogsConfig();
}
export const processContent = (data, buttonType) => Object.entries(data)
.map(([key, value]) => {
const isTitle = value === 'title';
const isButton = key === buttonType;
const isBoolean = typeof value === 'boolean';
const isHidden = isBoolean && value === false;
getLogs = (older_than, page, initial) => {
if (this.props.queryLogs.enabled) {
this.props.getLogs({
older_than, page, pageSize: TABLE_DEFAULT_PAGE_SIZE, initial,
let keyClass = 'key-colon';
if (isTitle) {
keyClass = 'title--border';
}
if (isButton || isBoolean) {
keyClass = '';
}
return isHidden ? null : <Fragment key={key}>
<div
className={`key__${key} ${keyClass} ${(isBoolean && value === true) ? 'font-weight-bold' : ''}`}>
<Trans>{isButton ? value : key}</Trans>
</div>
<div className={`value__${key} text-pre text-truncate`}>
<Trans>{(isTitle || isButton || isBoolean) ? '' : value || '—'}</Trans>
</div>
</Fragment>;
});
const Logs = (props) => {
const dispatch = useDispatch();
const [isSmallScreen, setIsSmallScreen] = useState(window.innerWidth < smallScreenSize);
const [detailedDataCurrent, setDetailedDataCurrent] = useState({});
const [buttonType, setButtonType] = useState(BLOCK_ACTIONS.BLOCK);
const [isModalOpened, setModalOpened] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const {
filtering,
setLogsPage,
setLogsPagination,
setLogsFilter,
toggleDetailedLogs,
dashboard,
dnsConfig,
queryLogs: {
filter,
enabled,
processingGetConfig,
processingAdditionalLogs,
processingGetLogs,
oldest,
logs,
pages,
page,
isDetailed,
},
} = props;
const mediaQuery = window.matchMedia(`(max-width: ${smallScreenSize}px)`);
const mediaQueryHandler = (e) => {
setIsSmallScreen(e.matches);
if (e.matches) {
toggleDetailedLogs(false);
}
};
useEffect(() => {
mediaQuery.addListener(mediaQueryHandler);
return () => mediaQuery.removeListener(mediaQueryHandler);
}, []);
const closeModal = () => setModalOpened(false);
const getLogs = (older_than, page, initial) => {
if (props.queryLogs.enabled) {
props.getLogs({
older_than,
page,
pageSize: TABLE_DEFAULT_PAGE_SIZE,
initial,
});
}
};
refreshLogs = () => {
window.location.reload();
useEffect(() => {
(async () => {
setIsLoading(true);
dispatch(setLogsPage(TABLE_FIRST_PAGE));
dispatch(getFilteringStatus());
dispatch(getClients());
try {
await Promise.all([
getLogs(...INITIAL_REQUEST_DATA),
dispatch(getLogsConfig()),
dispatch(getDnsConfig()),
]);
} catch (err) {
console.error(err);
} finally {
setIsLoading(false);
}
})();
}, []);
const refreshLogs = async () => {
setIsLoading(true);
await Promise.all([
dispatch(setLogsPage(TABLE_FIRST_PAGE)),
getLogs(...INITIAL_REQUEST_DATA),
]);
dispatch(addSuccessToast('query_log_updated'));
setIsLoading(false);
};
renderTooltip = (isFiltered, rule, filter, service) => isFiltered
&& <PopoverFiltered rule={rule} filter={filter} service={service} />;
renderResponseList = (response, status) => {
if (response.length > 0) {
const listItems = response.map((response, index) => (
<li key={index} title={response} className="logs__list-item">
{response}
</li>
));
return <ul className="list-unstyled">{listItems}</ul>;
}
return (
<div>
<Trans values={{ value: status }}>query_log_response_status</Trans>
</div>
);
};
toggleBlocking = (type, domain) => {
const { userRules } = this.props.filtering;
const { t } = this.props;
const lineEnding = !endsWith(userRules, '\n') ? '\n' : '';
const baseRule = `||${domain}^$important`;
const baseUnblocking = `@@${baseRule}`;
const blockingRule = type === 'block' ? baseUnblocking : baseRule;
const unblockingRule = type === 'block' ? baseRule : baseUnblocking;
const preparedBlockingRule = new RegExp(`(^|\n)${escapeRegExp(blockingRule)}($|\n)`);
const preparedUnblockingRule = new RegExp(`(^|\n)${escapeRegExp(unblockingRule)}($|\n)`);
if (userRules.match(preparedBlockingRule)) {
this.props.setRules(userRules.replace(`${blockingRule}`, ''));
this.props.addSuccessToast(`${t('rule_removed_from_custom_filtering_toast')}: ${blockingRule}`);
} else if (!userRules.match(preparedUnblockingRule)) {
this.props.setRules(`${userRules}${lineEnding}${unblockingRule}\n`);
this.props.addSuccessToast(`${t('rule_added_to_custom_filtering_toast')}: ${unblockingRule}`);
}
this.props.getFilteringStatus();
};
renderBlockingButton(isFiltered, domain) {
const buttonClass = isFiltered ? 'btn-outline-secondary' : 'btn-outline-danger';
const buttonText = isFiltered ? 'unblock_btn' : 'block_btn';
const buttonType = isFiltered ? 'unblock' : 'block';
return (
<div className="logs__action">
<button
type="button"
className={`btn btn-sm ${buttonClass}`}
onClick={() => this.toggleBlocking(buttonType, domain)}
disabled={this.props.filtering.processingRules}
>
<Trans>{buttonText}</Trans>
</button>
</div>
);
}
getDateCell = (row) => CellWrap(
row,
(isToday(row.value) ? formatTime : formatDateTime),
formatDateTime,
return (
<>
{enabled && processingGetConfig && <Loading />}
{enabled && !processingGetConfig && (
<Fragment>
<Filters
filter={filter}
setIsLoading={setIsLoading}
processingGetLogs={processingGetLogs}
processingAdditionalLogs={processingAdditionalLogs}
setLogsFilter={setLogsFilter}
refreshLogs={refreshLogs}
/>
<Table
isLoading={isLoading}
setIsLoading={setIsLoading}
logs={logs}
pages={pages}
page={page}
autoClients={dashboard.autoClients}
oldest={oldest}
filtering={filtering}
processingGetLogs={processingGetLogs}
processingGetConfig={processingGetConfig}
isDetailed={isDetailed}
setLogsPagination={setLogsPagination}
setLogsPage={setLogsPage}
toggleDetailedLogs={toggleDetailedLogs}
getLogs={getLogs}
setRules={props.setRules}
addSuccessToast={props.addSuccessToast}
getFilteringStatus={props.getFilteringStatus}
dnssec_enabled={dnsConfig.dnssec_enabled}
setDetailedDataCurrent={setDetailedDataCurrent}
setButtonType={setButtonType}
setModalOpened={setModalOpened}
isSmallScreen={isSmallScreen}
/>
<Modal portalClassName='grid' isOpen={isSmallScreen && isModalOpened}
onRequestClose={closeModal}
style={{
content: {
width: '100%',
height: 'fit-content',
left: 0,
top: 47,
padding: '1rem 1.5rem 1rem',
},
overlay: {
backgroundColor: 'rgba(0,0,0,0.5)',
},
}}
>
<svg
className="icon icon--small icon-cross d-block d-md-none cursor--pointer"
onClick={closeModal}>
<use xlinkHref="#cross" />
</svg>
{processContent(detailedDataCurrent, buttonType)}
</Modal>
</Fragment>
)}
{!enabled && !processingGetConfig && (
<Disabled />
)}
</>
);
getDomainCell = (row) => {
const response = row.value;
const trackerData = getTrackerData(response);
return (
<div className="logs__row" title={response}>
<div className="logs__text">{response}</div>
{trackerData && <Popover data={trackerData} />}
</div>
);
};
normalizeResponse = (response) => (
response.map((response) => {
const { value, type, ttl } = response;
return `${type}: ${value} (ttl=${ttl})`;
})
);
getFilterName = (filters, whitelistFilters, filterId, t) => {
if (filterId === CUSTOM_FILTERING_RULES_ID) {
return t('custom_filter_rules');
}
const filter = filters.find((filter) => filter.id === filterId)
|| whitelistFilters.find((filter) => filter.id === filterId);
let filterName = '';
if (filter) {
filterName = filter.name;
}
if (!filterName) {
filterName = t('unknown_filter', { filterId });
}
return filterName;
}
getResponseCell = ({ value: responses, original }) => {
const {
reason, filterId, rule, status, originalAnswer,
} = original;
const { t, filtering } = this.props;
const { filters, whitelistFilters } = filtering;
const isFiltered = checkFiltered(reason);
const isBlackList = checkBlackList(reason);
const isRewrite = checkRewrite(reason);
const isRewriteAuto = checkRewriteHosts(reason);
const isWhiteList = checkWhiteList(reason);
const isBlockedService = checkBlockedService(reason);
const isBlockedCnameIp = originalAnswer;
const filterKey = reason.replace(FILTERED, '');
const parsedFilteredReason = t('query_log_filtered', { filter: filterKey });
const currentService = SERVICES.find((service) => service.id === original.serviceName);
const serviceName = currentService && currentService.name;
const filterName = this.getFilterName(filters, whitelistFilters, filterId, t);
if (isBlockedCnameIp) {
const normalizedAnswer = this.normalizeResponse(originalAnswer);
return (
<div className="logs__row logs__row--column">
<div className="logs__text-wrap">
<span className="logs__text">
<Trans>blocked_by_response</Trans>
</span>
{this.renderTooltip(isFiltered, rule, filterName)}
</div>
<div className="logs__list-wrap">
{this.renderResponseList(normalizedAnswer, status)}
</div>
</div>
);
}
return (
<div className="logs__row logs__row--column">
<div className="logs__text-wrap">
{(isFiltered || isBlockedService) && !isBlackList && (
<span className="logs__text" title={parsedFilteredReason}>
{parsedFilteredReason}
</span>
)}
{isBlackList && (
<span className="logs__text">
<Trans values={{ filter: filterName }}>
query_log_filtered
</Trans>
</span>
)}
{isBlockedService
? this.renderTooltip(isFiltered, '', '', serviceName)
: this.renderTooltip(isFiltered, rule, filterName)}
{isRewrite && (
<strong>
<Trans>rewrite_applied</Trans>
</strong>
)}
{isRewriteAuto && (
<span className="logs__text">
<strong>
<Trans>rewrite_hosts_applied</Trans>
</strong>
</span>
)}
</div>
<div className="logs__list-wrap">
{this.renderResponseList(responses, status)}
{isWhiteList && this.renderTooltip(isWhiteList, rule, filterName)}
</div>
</div>
);
};
getClientCell = (row) => {
const { original } = row;
const { t } = this.props;
const { reason, domain } = original;
const isFiltered = checkFiltered(reason);
const isRewrite = checkRewrite(reason);
const isAutoRewrite = checkRewriteHosts(reason);
if (isAutoRewrite) {
return (
<div className="logs__row logs__row--overflow logs__row--column">
{formatClientCell(row, t)}
</div>
);
}
return (
<Fragment>
<div className="logs__row logs__row--overflow logs__row--column">
{formatClientCell(row, t)}
</div>
{isRewrite ? (
<div className="logs__action">
<Link to="/dns_rewrites" className="btn btn-sm btn-outline-primary">
<Trans>configure</Trans>
</Link>
</div>
) : (
this.renderBlockingButton(isFiltered, domain)
)}
</Fragment>
);
};
fetchData = (state) => {
const { pages } = state;
const { oldest, page } = this.props.queryLogs;
const isLastPage = pages && (page + 1 === pages);
if (isLastPage) {
this.getLogs(oldest, page);
}
};
changePage = (page) => {
this.props.setLogsPage(page);
this.props.setLogsPagination({ page, pageSize: TABLE_DEFAULT_PAGE_SIZE });
};
renderLogs() {
const { queryLogs, t } = this.props;
const {
processingGetLogs, processingGetConfig, logs, pages, page,
} = queryLogs;
const isLoading = processingGetLogs || processingGetConfig;
const columns = [
{
Header: t('time_table_header'),
accessor: 'time',
minWidth: 105,
Cell: this.getDateCell,
},
{
Header: t('domain_name_table_header'),
accessor: 'domain',
minWidth: 180,
Cell: this.getDomainCell,
},
{
Header: t('type_table_header'),
accessor: 'type',
maxWidth: 60,
},
{
Header: t('response_table_header'),
accessor: 'response',
minWidth: 250,
Cell: this.getResponseCell,
},
{
Header: t('client_table_header'),
accessor: 'client',
maxWidth: 240,
minWidth: 240,
Cell: this.getClientCell,
},
];
return (
<ReactTable
manual
minRows={5}
page={page}
pages={pages}
columns={columns}
filterable={false}
sortable={false}
data={logs || []}
loading={isLoading}
showPagination={true}
showPaginationTop={true}
showPageJump={false}
showPageSizeOptions={false}
onFetchData={this.fetchData}
onPageChange={this.changePage}
className="logs__table"
defaultPageSize={TABLE_DEFAULT_PAGE_SIZE}
previousText={t('previous_btn')}
nextText={t('next_btn')}
loadingText={t('loading_table_status')}
rowsText={t('rows_table_footer_text')}
noDataText={t('no_logs_found')}
pageText={''}
ofText={''}
renderTotalPagesCount={() => false}
defaultFilterMethod={(filter, row) => {
const id = filter.pivotId || filter.id;
return row[id] !== undefined
? String(row[id]).indexOf(filter.value) !== -1
: true;
}}
defaultSorted={[
{
id: 'time',
desc: true,
},
]}
getTrProps={(_state, rowInfo) => {
if (!rowInfo) {
return {};
}
const { reason } = rowInfo.original;
if (checkFiltered(reason)) {
return {
className: 'red',
};
} if (checkWhiteList(reason)) {
return {
className: 'green',
};
} if (checkRewrite(reason) || checkRewriteHosts(reason)) {
return {
className: 'blue',
};
}
return {
className: '',
};
}}
/>
);
}
render() {
const { queryLogs, t } = this.props;
const {
enabled, processingGetConfig, processingAdditionalLogs, processingGetLogs,
} = queryLogs;
const refreshButton = enabled ? (
<button
type="button"
className="btn btn-icon btn-outline-primary btn-sm ml-3"
onClick={this.refreshLogs}
>
<svg className="icons">
<use xlinkHref="#refresh" />
</svg>
</button>
) : (
''
);
return (
<Fragment>
<PageTitle title={t('query_log')}>{refreshButton}</PageTitle>
{enabled && processingGetConfig && <Loading />}
{enabled && !processingGetConfig && (
<Fragment>
<Filters
filter={queryLogs.filter}
processingGetLogs={processingGetLogs}
processingAdditionalLogs={processingAdditionalLogs}
setLogsFilter={this.props.setLogsFilter}
/>
<Card>{this.renderLogs()}</Card>
</Fragment>
)}
{!enabled && !processingGetConfig && (
<Card>
<div className="lead text-center py-6">
<Trans
components={[
<Link to="/settings#logs-config" key="0">
link
</Link>,
]}
>
query_log_disabled
</Trans>
</div>
</Card>
)}
</Fragment>
);
}
}
};
Logs.propTypes = {
getLogs: PropTypes.func.isRequired,
@@ -461,12 +214,11 @@ Logs.propTypes = {
filtering: PropTypes.object.isRequired,
setRules: PropTypes.func.isRequired,
addSuccessToast: PropTypes.func.isRequired,
getClients: PropTypes.func.isRequired,
getLogsConfig: PropTypes.func.isRequired,
setLogsPagination: PropTypes.func.isRequired,
setLogsFilter: PropTypes.func.isRequired,
setLogsPage: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
toggleDetailedLogs: PropTypes.func.isRequired,
dnsConfig: PropTypes.object.isRequired,
};
export default withTranslation()(Logs);
export default Logs;

View File

@@ -79,16 +79,26 @@ class AutoClients extends Component {
},
]}
className="-striped -highlight card-table-overflow"
showPagination={true}
showPagination
defaultPageSize={10}
minRows={5}
previousText={t('previous_btn')}
nextText={t('next_btn')}
showPageSizeOptions={false}
showPageJump={false}
renderTotalPagesCount={() => false}
previousText={
<svg className="icons icon--small icon--gray w-100 h-100">
<use xlinkHref="#arrow-left" />
</svg>}
nextText={
<svg className="icons icon--small icon--gray w-100 h-100">
<use xlinkHref="#arrow-right" />
</svg>}
loadingText={t('loading_table_status')}
pageText={t('page_table_footer_text')}
ofText="/"
pageText=''
ofText=''
rowsText={t('rows_table_footer_text')}
noDataText={t('clients_not_found')}
getPaginationProps={() => ({ className: 'custom-pagination' })}
/>
</Card>
);

View File

@@ -41,7 +41,7 @@ class ClientsTable extends Component {
}
}
if (this.props.modalType === MODAL_TYPE.EDIT) {
if (this.props.modalType === MODAL_TYPE.EDIT_FILTERS) {
this.handleFormUpdate(config, this.props.modalClientName);
} else {
this.handleFormAdd(config);
@@ -91,7 +91,7 @@ class ClientsTable extends Component {
const { value } = row;
return (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
<span className="logs__text">
{value.map((address) => (
<div key={address} title={address}>
@@ -121,7 +121,7 @@ class ClientsTable extends Component {
);
return (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
<div className="logs__text">{title}</div>
</div>
);
@@ -167,7 +167,7 @@ class ClientsTable extends Component {
);
return (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
<div className="logs__text">{title}</div>
</div>
);
@@ -185,7 +185,7 @@ class ClientsTable extends Component {
}
return (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
<span className="logs__text">
{value.map((tag) => (
<div key={tag} title={tag} className="small">
@@ -221,7 +221,7 @@ class ClientsTable extends Component {
type="button"
className="btn btn-icon btn-outline-primary btn-sm mr-2"
onClick={() => toggleClientModal({
type: MODAL_TYPE.EDIT,
type: MODAL_TYPE.EDIT_FILTERS,
name: clientName,
})
}
@@ -282,21 +282,31 @@ class ClientsTable extends Component {
},
]}
className="-striped -highlight card-table-overflow"
showPagination={true}
showPagination
defaultPageSize={10}
minRows={5}
previousText={t('previous_btn')}
nextText={t('next_btn')}
showPageSizeOptions={false}
showPageJump={false}
renderTotalPagesCount={() => false}
previousText={
<svg className="icons icon--small icon--gray w-100 h-100">
<use xlinkHref="#arrow-left" />
</svg>}
nextText={
<svg className="icons icon--small icon--gray w-100 h-100">
<use xlinkHref="#arrow-right" />
</svg>}
loadingText={t('loading_table_status')}
pageText={t('page_table_footer_text')}
ofText="/"
pageText=''
ofText=''
rowsText={t('rows_table_footer_text')}
noDataText={t('clients_not_found')}
getPaginationProps={() => ({ className: 'custom-pagination' })}
/>
<button
type="button"
className="btn btn-success btn-standard mt-3"
onClick={() => toggleClientModal(MODAL_TYPE.ADD)}
onClick={() => toggleClientModal(MODAL_TYPE.ADD_FILTERS)}
disabled={processingAdding}
>
<Trans>client_add</Trans>

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import {
@@ -13,14 +13,13 @@ import Tabs from '../../ui/Tabs';
import Examples from '../Dns/Upstream/Examples';
import { toggleAllServices } from '../../../helpers/helpers';
import {
required,
clientId,
renderInputField,
renderGroupField,
renderSelectField,
renderServiceField,
} from '../../../helpers/form';
import { SERVICES } from '../../../helpers/constants';
import { validateClientId, validateRequiredValue } from '../../../helpers/validators';
import { FORM_NAME, SERVICES } from '../../../helpers/constants';
import './Service.css';
const settingsCheckboxes = [
@@ -48,12 +47,12 @@ const settingsCheckboxes = [
const validate = (values) => {
const errors = {};
const { name, ids } = values;
errors.name = required(name);
errors.name = validateRequiredValue(name);
if (ids && ids.length) {
const idArrayErrors = [];
ids.forEach((id, idx) => {
idArrayErrors[idx] = required(id) || clientId(id);
idArrayErrors[idx] = validateRequiredValue(id) || validateClientId(id);
});
if (idArrayErrors.length) {
@@ -63,7 +62,6 @@ const validate = (values) => {
return errors;
};
const renderFieldsWrapper = (placeholder, buttonTitle) => function cell(row) {
const {
fields,
@@ -90,7 +88,7 @@ const renderFieldsWrapper = (placeholder, buttonTitle) => function cell(row) {
onClick={() => fields.push()}
title={buttonTitle}
>
<svg className="icon icon--close">
<svg className="icon icon--small">
<use xlinkHref="#plus" />
</svg>
</button>
@@ -122,7 +120,7 @@ const renderMultiselect = (props) => {
renderMultiselect.propTypes = {
input: PropTypes.object.isRequired,
placeholder: PropTypes.string,
options: PropTypes.object,
options: PropTypes.array,
};
let Form = (props) => {
@@ -142,6 +140,101 @@ let Form = (props) => {
tagsOptions,
} = props;
const [activeTabLabel, setActiveTabLabel] = useState('settings');
const tabs = {
settings: {
title: 'settings',
component: <div label="settings" title={props.t('main_settings')}>
{settingsCheckboxes.map((setting) => (
<div className="form__group" key={setting.name}>
<Field
name={setting.name}
type="checkbox"
component={renderSelectField}
placeholder={t(setting.placeholder)}
disabled={
setting.name !== 'use_global_settings'
? useGlobalSettings
: false
}
/>
</div>
))}
</div>,
},
block_services: {
title: 'block_services',
component: <div label="services" title={props.t('block_services')}>
<div className="form__group">
<Field
name="use_global_blocked_services"
type="checkbox"
component={renderServiceField}
placeholder={t('blocked_services_global')}
modifier="service--global"
/>
<div className="row mb-4">
<div className="col-6">
<button
type="button"
className="btn btn-secondary btn-block"
disabled={useGlobalServices}
onClick={() => toggleAllServices(SERVICES, change, true)}
>
<Trans>block_all</Trans>
</button>
</div>
<div className="col-6">
<button
type="button"
className="btn btn-secondary btn-block"
disabled={useGlobalServices}
onClick={() => toggleAllServices(SERVICES, change, false)}
>
<Trans>unblock_all</Trans>
</button>
</div>
</div>
<div className="services">
{SERVICES.map((service) => (
<Field
key={service.id}
icon={`service_${service.id}`}
name={`blocked_services.${service.id}`}
type="checkbox"
component={renderServiceField}
placeholder={service.name}
disabled={useGlobalServices}
/>
))}
</div>
</div>
</div>,
},
upstream_dns: {
title: 'upstream_dns',
component: <div label="upstream" title={props.t('upstream_dns')}>
<div className="form__desc mb-3">
<Trans components={[<a href="#dns" key="0">link</a>]}>
upstream_dns_client_desc
</Trans>
</div>
<Field
id="upstreams"
name="upstreams"
component="textarea"
type="text"
className="form-control form-control--textarea mb-5"
placeholder={t('upstream_dns')}
/>
<Examples />
</div>,
},
};
const activeTab = tabs[activeTabLabel].component;
return (
<form onSubmit={handleSubmit}>
<div className="modal-body">
@@ -207,86 +300,9 @@ let Form = (props) => {
</div>
</div>
<Tabs controlClass="form">
<div label="settings" title={props.t('main_settings')}>
{settingsCheckboxes.map((setting) => (
<div className="form__group" key={setting.name}>
<Field
name={setting.name}
type="checkbox"
component={renderSelectField}
placeholder={t(setting.placeholder)}
disabled={
setting.name !== 'use_global_settings'
? useGlobalSettings
: false
}
/>
</div>
))}
</div>
<div label="services" title={props.t('block_services')}>
<div className="form__group">
<Field
name="use_global_blocked_services"
type="checkbox"
component={renderServiceField}
placeholder={t('blocked_services_global')}
modifier="service--global"
/>
<div className="row mb-4">
<div className="col-6">
<button
type="button"
className="btn btn-secondary btn-block"
disabled={useGlobalServices}
onClick={() => toggleAllServices(SERVICES, change, true)}
>
<Trans>block_all</Trans>
</button>
</div>
<div className="col-6">
<button
type="button"
className="btn btn-secondary btn-block"
disabled={useGlobalServices}
onClick={() => toggleAllServices(SERVICES, change, false)}
>
<Trans>unblock_all</Trans>
</button>
</div>
</div>
<div className="services">
{SERVICES.map((service) => (
<Field
key={service.id}
icon={`service_${service.id}`}
name={`blocked_services.${service.id}`}
type="checkbox"
component={renderServiceField}
placeholder={service.name}
disabled={useGlobalServices}
/>
))}
</div>
</div>
</div>
<div label="upstream" title={props.t('upstream_dns')}>
<div className="form__desc mb-3">
<Trans components={[<a href="#dns" key="0">link</a>]}>
upstream_dns_client_desc
</Trans>
</div>
<Field
id="upstreams"
name="upstreams"
component="textarea"
type="text"
className="form-control form-control--textarea mb-5"
placeholder={t('upstream_dns')}
/>
<Examples />
</div>
<Tabs controlClass="form" tabs={tabs} activeTabLabel={activeTabLabel}
setActiveTabLabel={setActiveTabLabel}>
{activeTab}
</Tabs>
</div>
@@ -338,7 +354,7 @@ Form.propTypes = {
tagsOptions: PropTypes.array.isRequired,
};
const selector = formValueSelector('clientForm');
const selector = formValueSelector(FORM_NAME.CLIENT);
Form = connect((state) => {
const useGlobalSettings = selector(state, 'use_global_settings');
@@ -352,7 +368,7 @@ Form = connect((state) => {
export default flow([
withTranslation(),
reduxForm({
form: 'clientForm',
form: FORM_NAME.CLIENT,
enableReinitialize: true,
validate,
}),

View File

@@ -47,7 +47,7 @@ const Modal = (props) => {
<div className="modal-content">
<div className="modal-header">
<h4 className="modal-title">
{modalType === MODAL_TYPE.EDIT ? (
{modalType === MODAL_TYPE.EDIT_FILTERS ? (
<Trans>client_edit</Trans>
) : (
<Trans>client_new</Trans>

View File

@@ -32,11 +32,9 @@ const getFormattedWhois = (value, t) => {
const whoisCell = (t) => function cell(row) {
const { value } = row;
return (
<div className="logs__row logs__row--overflow">
<span className="logs__text logs__text--wrap">{getFormattedWhois(value, t)}</span>
</div>
);
return <div className="logs__row o-hidden">
<div className="logs__text logs__text--wrap">{getFormattedWhois(value, t)}</div>
</div>;
};
export default whoisCell;

View File

@@ -4,10 +4,9 @@ import PropTypes from 'prop-types';
import { Field, reduxForm, formValueSelector } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import {
renderInputField, required, ipv4, isPositive, toNumber,
} from '../../../helpers/form';
import { renderInputField, toNumber } from '../../../helpers/form';
import { FORM_NAME } from '../../../helpers/constants';
import { validateIpv4, validateIsPositiveValue, validateRequiredValue } from '../../../helpers/validators';
const renderInterfaces = ((interfaces) => (
Object.keys(interfaces).map((item) => {
@@ -95,7 +94,7 @@ let Form = (props) => {
name="interface_name"
component="select"
className="form-control custom-select"
validate={[required]}
validate={[validateRequiredValue]}
>
<option value="" disabled={enabled}>
{t('dhcp_interface_select')}
@@ -124,7 +123,7 @@ let Form = (props) => {
type="text"
className="form-control"
placeholder={t('dhcp_form_gateway_input')}
validate={[ipv4, required]}
validate={[validateIpv4, validateRequiredValue]}
/>
</div>
<div className="form__group form__group--settings">
@@ -136,7 +135,7 @@ let Form = (props) => {
type="text"
className="form-control"
placeholder={t('dhcp_form_subnet_input')}
validate={[ipv4, required]}
validate={[validateIpv4, validateRequiredValue]}
/>
</div>
</div>
@@ -154,7 +153,7 @@ let Form = (props) => {
type="text"
className="form-control"
placeholder={t('dhcp_form_range_start')}
validate={[ipv4, required]}
validate={[validateIpv4, validateRequiredValue]}
/>
</div>
<div className="col">
@@ -165,7 +164,7 @@ let Form = (props) => {
type="text"
className="form-control"
placeholder={t('dhcp_form_range_end')}
validate={[ipv4, required]}
validate={[validateIpv4, validateRequiredValue]}
/>
</div>
</div>
@@ -178,7 +177,7 @@ let Form = (props) => {
type="number"
className="form-control"
placeholder={t('dhcp_form_lease_input')}
validate={[required, isPositive]}
validate={[validateRequiredValue, validateIsPositiveValue]}
normalize={toNumber}
/>
</div>
@@ -221,7 +220,7 @@ Form.propTypes = {
change: PropTypes.func.isRequired,
};
const selector = formValueSelector('dhcpForm');
const selector = formValueSelector(FORM_NAME.DHCP);
Form = connect((state) => {
const interfaceValue = selector(state, 'interface_name');
@@ -232,5 +231,5 @@ Form = connect((state) => {
export default flow([
withTranslation(),
reduxForm({ form: 'dhcpForm' }),
reduxForm({ form: FORM_NAME.DHCP }),
])(Form);

View File

@@ -2,11 +2,11 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ReactTable from 'react-table';
import { Trans, withTranslation } from 'react-i18next';
import { SMALL_TABLE_DEFAULT_PAGE_SIZE } from '../../../helpers/constants';
import { LEASES_TABLE_DEFAULT_PAGE_SIZE } from '../../../helpers/constants';
class Leases extends Component {
cellWrap = ({ value }) => (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
<span className="logs__text" title={value}>
{value}
</span>
@@ -37,9 +37,9 @@ class Leases extends Component {
Cell: this.cellWrap,
},
]}
pageSize={SMALL_TABLE_DEFAULT_PAGE_SIZE}
pageSize={LEASES_TABLE_DEFAULT_PAGE_SIZE}
showPageSizeOptions={false}
showPagination={leases.length > SMALL_TABLE_DEFAULT_PAGE_SIZE}
showPagination={leases.length > LEASES_TABLE_DEFAULT_PAGE_SIZE}
noDataText={t('dhcp_leases_not_found')}
minRows={6}
className="-striped -highlight card-table-overflow"

View File

@@ -3,10 +3,9 @@ import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import {
renderInputField, ipv4, mac, required,
} from '../../../../helpers/form';
import { renderInputField } from '../../../../helpers/form';
import { validateIpv4, validateMac, validateRequiredValue } from '../../../../helpers/validators';
import { FORM_NAME } from '../../../../helpers/constants';
const Form = (props) => {
const {
@@ -30,7 +29,7 @@ const Form = (props) => {
type="text"
className="form-control"
placeholder={t('form_enter_mac')}
validate={[required, mac]}
validate={[validateRequiredValue, validateMac]}
/>
</div>
<div className="form__group">
@@ -41,7 +40,7 @@ const Form = (props) => {
type="text"
className="form-control"
placeholder={t('form_enter_ip')}
validate={[required, ipv4]}
validate={[validateRequiredValue, validateIpv4]}
/>
</div>
<div className="form__group">
@@ -94,5 +93,5 @@ Form.propTypes = {
export default flow([
withTranslation(),
reduxForm({ form: 'leaseForm' }),
reduxForm({ form: FORM_NAME.LEASE }),
])(Form);

View File

@@ -2,13 +2,13 @@ import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import ReactTable from 'react-table';
import { Trans, withTranslation } from 'react-i18next';
import { SMALL_TABLE_DEFAULT_PAGE_SIZE } from '../../../../helpers/constants';
import { LEASES_TABLE_DEFAULT_PAGE_SIZE } from '../../../../helpers/constants';
import Modal from './Modal';
class StaticLeases extends Component {
cellWrap = ({ value }) => (
<div className="logs__row logs__row--overflow">
<div className="logs__row o-hidden">
<span className="logs__text" title={value}>
{value}
</span>
@@ -67,7 +67,7 @@ class StaticLeases extends Component {
<div className="logs__row logs__row--center">
<button
type="button"
className="btn btn-icon btn-outline-secondary btn-sm"
className="btn btn-icon btn-icon--green btn-outline-secondary btn-sm"
title={t('delete_table_action')}
disabled={processingDeleting}
onClick={() => this.handleDelete(ip, mac, hostname)
@@ -82,9 +82,9 @@ class StaticLeases extends Component {
},
},
]}
pageSize={SMALL_TABLE_DEFAULT_PAGE_SIZE}
pageSize={LEASES_TABLE_DEFAULT_PAGE_SIZE}
showPageSizeOptions={false}
showPagination={staticLeases.length > SMALL_TABLE_DEFAULT_PAGE_SIZE}
showPagination={staticLeases.length > LEASES_TABLE_DEFAULT_PAGE_SIZE}
noDataText={t('dhcp_static_leases_not_found')}
className="-striped -highlight card-table-overflow"
minRows={6}

View File

@@ -32,7 +32,7 @@ class Dhcp extends Component {
const {
config, check, processingDhcp, processingConfig,
} = this.props.dhcp;
const otherDhcpFound = check && check.otherServer
const otherDhcpFound = check?.otherServer
&& check.otherServer.found === DHCP_STATUS_RESPONSE.YES;
const filledConfig = Object.keys(config).every((key) => {
if (key === 'enabled' || key === 'icmp_timeout_msec') {

View File

@@ -5,6 +5,7 @@ import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import { renderTextareaField } from '../../../../helpers/form';
import { normalizeMultiline } from '../../../../helpers/helpers';
import { FORM_NAME } from '../../../../helpers/constants';
const fields = [
{
@@ -45,7 +46,7 @@ const Form = (props) => {
type="text"
className="form-control form-control--textarea font-monospace"
disabled={disabled}
normalizeOnBlur={normalizeMultiline}
normalizeOnBlur={id === 'disallowed_clients' ? normalizeMultiline : undefined}
/>
</div>;
@@ -84,4 +85,4 @@ Form.propTypes = {
textarea: PropTypes.bool,
};
export default flow([withTranslation(), reduxForm({ form: 'accessForm' })])(Form);
export default flow([withTranslation(), reduxForm({ form: FORM_NAME.ACCESS })])(Form);

View File

@@ -0,0 +1,95 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import { Trans, useTranslation } from 'react-i18next';
import { shallowEqual, useSelector } from 'react-redux';
import { renderInputField, toNumber } from '../../../../helpers/form';
import { validateBiggerOrEqualZeroValue, getMaxValueValidator, validateRequiredValue } from '../../../../helpers/validators';
import { FORM_NAME, SECONDS_IN_HOUR } from '../../../../helpers/constants';
const validateMaxValue3600 = getMaxValueValidator(SECONDS_IN_HOUR);
const getInputFields = ({ validateRequiredValue, validateMaxValue3600 }) => [{
name: 'cache_size',
title: 'cache_size',
description: 'cache_size_desc',
placeholder: 'enter_cache_size',
validate: validateRequiredValue,
},
{
name: 'cache_ttl_min',
title: 'cache_ttl_min_override',
description: 'cache_ttl_min_override_desc',
placeholder: 'enter_cache_ttl_min_override',
max: SECONDS_IN_HOUR,
validate: validateMaxValue3600,
},
{
name: 'cache_ttl_max',
title: 'cache_ttl_max_override',
description: 'cache_ttl_max_override_desc',
placeholder: 'enter_cache_ttl_max_override',
}];
const Form = ({
handleSubmit, submitting, invalid,
}) => {
const { t } = useTranslation();
const { processingSetConfig } = useSelector((state) => state.dnsConfig, shallowEqual);
const {
cache_ttl_max, cache_ttl_min,
} = useSelector((state) => state.form[FORM_NAME.CACHE].values, shallowEqual);
const minExceedsMax = cache_ttl_min > cache_ttl_max;
const INPUTS_FIELDS = getInputFields({
validateRequiredValue,
validateMaxValue3600,
});
return <form onSubmit={handleSubmit}>
<div className="row">
{INPUTS_FIELDS.map(({
name, title, description, placeholder, validate, max,
}) => <div className="col-12" key={name}>
<div className="col-7 p-0">
<div className="form__group form__group--settings">
<label htmlFor={name}
className="form__label form__label--with-desc">{t(title)}</label>
<div className="form__desc form__desc--top">{t(description)}</div>
<Field
name={name}
type="number"
component={renderInputField}
placeholder={t(placeholder)}
disabled={processingSetConfig}
normalize={toNumber}
className="form-control"
validate={[validateBiggerOrEqualZeroValue].concat(validate || [])}
min={0}
max={max}
/>
</div>
</div>
</div>)}
{minExceedsMax
&& <span className="text-danger pl-3 pb-3">{t('min_exceeds_max_value')}</span>}
</div>
<button
type="submit"
className="btn btn-success btn-standard btn-large"
disabled={submitting || invalid || processingSetConfig || minExceedsMax}
>
<Trans>save_btn</Trans>
</button>
</form>;
};
Form.propTypes = {
handleSubmit: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired,
invalid: PropTypes.bool.isRequired,
};
export default reduxForm({ form: FORM_NAME.CACHE })(Form);

View File

@@ -0,0 +1,42 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import Card from '../../../ui/Card';
import Form from './Form';
import { setDnsConfig } from '../../../../actions/dnsConfig';
import { selectCompletedFields } from '../../../../helpers/helpers';
const CacheConfig = () => {
const { t } = useTranslation();
const dispatch = useDispatch();
const {
cache_size, cache_ttl_max, cache_ttl_min,
} = useSelector((state) => state.dnsConfig, shallowEqual);
const handleFormSubmit = (values) => {
const completedFields = selectCompletedFields(values);
dispatch(setDnsConfig(completedFields));
};
return (
<Card
title={t('dns_cache_config')}
subtitle={t('dns_cache_config_desc')}
bodyType="card-body box-body--settings"
id="dns-config"
>
<div className="form">
<Form
initialValues={{
cache_size,
cache_ttl_max,
cache_ttl_min,
}}
onSubmit={handleFormSubmit}
/>
</div>
</Card>
);
};
export default CacheConfig;

View File

@@ -4,18 +4,19 @@ import { connect } from 'react-redux';
import { Field, reduxForm, formValueSelector } from 'redux-form';
import { Trans, withTranslation } from 'react-i18next';
import flow from 'lodash/flow';
import {
renderInputField,
renderRadioField,
renderSelectField,
required,
ipv4,
ipv6,
biggerOrEqualZero,
toNumber,
} from '../../../../helpers/form';
import { BLOCKING_MODES } from '../../../../helpers/constants';
import {
validateBiggerOrEqualZeroValue,
validateIpv4,
validateIpv6,
validateRequiredValue,
} from '../../../../helpers/validators';
import { BLOCKING_MODES, FORM_NAME } from '../../../../helpers/constants';
const checkboxes = [{
name: 'edns_cs_enabled',
@@ -36,12 +37,12 @@ const checkboxes = [{
const customIps = [{
description: 'blocking_ipv4_desc',
name: 'blocking_ipv4',
validateIp: ipv4,
validateIp: validateIpv4,
},
{
description: 'blocking_ipv6_desc',
name: 'blocking_ipv6',
validateIp: ipv6,
validateIp: validateIpv6,
}];
const getFields = (processing, t) => Object.values(BLOCKING_MODES)
@@ -60,91 +61,91 @@ const getFields = (processing, t) => Object.values(BLOCKING_MODES)
let Form = ({
handleSubmit, submitting, invalid, processing, blockingMode, t,
}) => <form onSubmit={handleSubmit}>
<div className="row">
<div className="col-12 col-sm-6">
<div className="form__group form__group--settings">
<label htmlFor="ratelimit"
className="form__label form__label--with-desc">
<Trans>rate_limit</Trans>
</label>
<div className="form__desc form__desc--top">
<Trans>rate_limit_desc</Trans>
</div>
<Field
name="ratelimit"
type="number"
component={renderInputField}
className="form-control"
placeholder={t('form_enter_rate_limit')}
normalize={toNumber}
validate={[required, biggerOrEqualZero]}
/>
<div className="row">
<div className="col-12 col-sm-6">
<div className="form__group form__group--settings">
<label htmlFor="ratelimit"
className="form__label form__label--with-desc">
<Trans>rate_limit</Trans>
</label>
<div className="form__desc form__desc--top">
<Trans>rate_limit_desc</Trans>
</div>
<Field
name="ratelimit"
type="number"
component={renderInputField}
className="form-control"
placeholder={t('form_enter_rate_limit')}
normalize={toNumber}
validate={[validateRequiredValue, validateBiggerOrEqualZeroValue]}
/>
</div>
</div>
{checkboxes.map(({ name, placeholder, subtitle }) => <div className="col-12" key={name}>
<div className="form__group form__group--settings">
<Field
name={name}
type="checkbox"
component={renderSelectField}
placeholder={t(placeholder)}
disabled={processing}
subtitle={t(subtitle)}
/>
</div>
</div>)}
<div className="col-12">
<div className="form__group form__group--settings mb-4">
<label className="form__label form__label--with-desc">
<Trans>blocking_mode</Trans>
</label>
<div className="form__desc form__desc--top">
{Object.values(BLOCKING_MODES)
.map((mode) => (
<li key={mode}>
<Trans>{`blocking_mode_${mode}`}</Trans>
</li>
))}
</div>
<div className="custom-controls-stacked">
{getFields(processing, t)}
</div>
</div>
{checkboxes.map(({ name, placeholder, subtitle }) => <div className="col-12" key={name}>
</div>
{blockingMode === BLOCKING_MODES.custom_ip && (
<Fragment>
{customIps.map(({
description,
name,
validateIp,
}) => <div className="col-12 col-sm-6" key={name}>
<div className="form__group form__group--settings">
<label className="form__label form__label--with-desc"
htmlFor={name}><Trans>{name}</Trans>
</label>
<div className="form__desc form__desc--top">
<Trans>{description}</Trans>
</div>
<Field
name={name}
type="checkbox"
component={renderSelectField}
placeholder={t(placeholder)}
disabled={processing}
subtitle={t(subtitle)}
component={renderInputField}
className="form-control"
placeholder={t('form_enter_ip')}
validate={[validateIp, validateRequiredValue]}
/>
</div>
</div>)}
<div className="col-12">
<div className="form__group form__group--settings mb-4">
<label className="form__label form__label--with-desc">
<Trans>blocking_mode</Trans>
</label>
<div className="form__desc form__desc--top">
{Object.values(BLOCKING_MODES)
.map((mode) => (
<li key={mode}>
<Trans>{`blocking_mode_${mode}`}</Trans>
</li>
))}
</div>
<div className="custom-controls-stacked">
{getFields(processing, t)}
</div>
</div>
</div>
{blockingMode === BLOCKING_MODES.custom_ip && (
<Fragment>
{customIps.map(({
description,
name,
validateIp,
}) => <div className="col-12 col-sm-6" key={name}>
<div className="form__group form__group--settings">
<label className="form__label form__label--with-desc"
htmlFor={name}><Trans>{name}</Trans>
</label>
<div className="form__desc form__desc--top">
<Trans>{description}</Trans>
</div>
<Field
name={name}
component={renderInputField}
className="form-control"
placeholder={t('form_enter_ip')}
validate={[validateIp, required]}
/>
</div>
</div>)}
</Fragment>
)}
</div>
<button
type="submit"
className="btn btn-success btn-standard btn-large"
disabled={submitting || invalid || processing}
>
<Trans>save_btn</Trans>
</button>
</form>;
</Fragment>
)}
</div>
<button
type="submit"
className="btn btn-success btn-standard btn-large"
disabled={submitting || invalid || processing}
>
<Trans>save_btn</Trans>
</button>
</form>;
Form.propTypes = {
blockingMode: PropTypes.string.isRequired,
@@ -155,7 +156,7 @@ Form.propTypes = {
t: PropTypes.func.isRequired,
};
const selector = formValueSelector('blockingModeForm');
const selector = formValueSelector(FORM_NAME.BLOCKING_MODE);
Form = connect((state) => {
const blockingMode = selector(state, 'blocking_mode');
@@ -166,7 +167,5 @@ Form = connect((state) => {
export default flow([
withTranslation(),
reduxForm({
form: 'blockingModeForm',
}),
reduxForm({ form: FORM_NAME.BLOCKING_MODE }),
])(Form);

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