tbb-commits
Threads by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 20756 discussions
[tor-browser/tor-browser-91.4.0esr-11.5-1] fixup! Bug 10760: Integrate TorButton to TorBrowser core
by gk@torproject.org 08 Dec '21
by gk@torproject.org 08 Dec '21
08 Dec '21
commit b33897a4f757076cf10efc192b6da20878b4cca7
Author: Richard Pospesel <richard(a)torproject.org>
Date: Mon Dec 6 15:37:34 2021 +0100
fixup! Bug 10760: Integrate TorButton to TorBrowser core
---
browser/base/content/appmenu-viewcache.inc.xhtml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/browser/base/content/appmenu-viewcache.inc.xhtml b/browser/base/content/appmenu-viewcache.inc.xhtml
index 0812e0e84f45..a473509f1647 100644
--- a/browser/base/content/appmenu-viewcache.inc.xhtml
+++ b/browser/base/content/appmenu-viewcache.inc.xhtml
@@ -272,12 +272,12 @@
<toolbarbutton id="appMenuNewIdentity"
class="subviewbutton"
key="torbutton-new-identity-key"
- label="&torbutton.context_menu.new_identity;"
+ label="&torbutton.context_menu.new_identity_sentence_case;"
oncommand="torbutton_new_identity();"/>
<toolbarbutton id="appMenuNewCircuit"
class="subviewbutton"
key="torbutton-new-circuit-key"
- label="&torbutton.context_menu.new_circuit;"
+ label="&torbutton.context_menu.new_circuit_sentence_case;"
oncommand="torbutton_new_circuit();"/>
<toolbarseparator/>
<toolbarbutton id="appMenu-bookmarks-button"
1
0
[torbutton/master] Bug 40718: Application Menu items should be sentence case
by gk@torproject.org 08 Dec '21
by gk@torproject.org 08 Dec '21
08 Dec '21
commit 0a778de10f4f0822e376dfa8eefa63e5a699c865
Author: Richard Pospesel <richard(a)torproject.org>
Date: Mon Dec 6 15:35:59 2021 +0100
Bug 40718: Application Menu items should be sentence case
---
chrome/locale/en-US/torbutton.dtd | 2 ++
1 file changed, 2 insertions(+)
diff --git a/chrome/locale/en-US/torbutton.dtd b/chrome/locale/en-US/torbutton.dtd
index e5d56b64..cf744d25 100644
--- a/chrome/locale/en-US/torbutton.dtd
+++ b/chrome/locale/en-US/torbutton.dtd
@@ -1,6 +1,8 @@
<!ENTITY torbutton.context_menu.new_identity "New Identity">
+<!ENTITY torbutton.context_menu.new_identity_sentence_case "New identity">
<!ENTITY torbutton.context_menu.new_identity_key "I">
<!ENTITY torbutton.context_menu.new_circuit "New Tor Circuit for this Site">
+<!ENTITY torbutton.context_menu.new_circuit_sentence_case "New tor circuit for this site">
<!ENTITY torbutton.context_menu.new_circuit_key "C">
<!ENTITY torbutton.context_menu.networksettings "Tor Network Settings…">
<!ENTITY torbutton.context_menu.networksettings.key "N">
1
0
[torbutton/master] Merge remote-tracking branch 'gitlab/merge-requests/75'
by gk@torproject.org 08 Dec '21
by gk@torproject.org 08 Dec '21
08 Dec '21
commit dfde37e3c60fd2bbb68f1e3e7062dfcf1e03e81b
Merge: acb4d4aa 0a778de1
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Dec 8 10:10:19 2021 +0000
Merge remote-tracking branch 'gitlab/merge-requests/75'
chrome/locale/en-US/torbutton.dtd | 2 ++
1 file changed, 2 insertions(+)
1
0
08 Dec '21
commit 0bc9cbc484342f37853cfc3c6730e7d7a46055bf
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Dec 8 09:13:30 2021 +0000
Bug 40391: Fix clang config
---
projects/clang/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/clang/config b/projects/clang/config
index 11ea039..aeefc7a 100644
--- a/projects/clang/config
+++ b/projects/clang/config
@@ -14,7 +14,7 @@ input_files:
enable: '[% c("var/linux") %]'
- name: binutils
project: binutils
- enable: '[% c("var/linux") %] || [% c("var/android") %]'
+ enable: '[% c("var/linux") || c("var/android") %]'
- project: cmake
name: cmake
- project: llvm-project
1
0
[tor-browser/tor-browser-91.4.0esr-11.5-1] Revert "Bug 1724777, optimize suppressed MicroTask handling, r=mccr8 a=RyanVM"
by gk@torproject.org 07 Dec '21
by gk@torproject.org 07 Dec '21
07 Dec '21
commit 1542d19fd888586801eba130a6750ab0cbd93e9e
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Dec 7 16:19:15 2021 +0000
Revert "Bug 1724777, optimize suppressed MicroTask handling, r=mccr8 a=RyanVM"
This reverts commit 1eb1364357ac5bc2a4531337fb5416af39c3793f.
This fixes tor-browser#40721, tor-browser#40698, and tor-browser#40706.
---
dom/base/Document.cpp | 12 ------
dom/base/Document.h | 8 +++-
dom/base/test/mochitest.ini | 2 -
dom/base/test/test_suppressed_microtasks.html | 62 ---------------------------
dom/workers/RuntimeService.cpp | 4 +-
dom/workers/WorkerPrivate.cpp | 2 +-
dom/worklet/WorkletThread.cpp | 2 +-
xpcom/base/CycleCollectedJSContext.cpp | 51 ++++++----------------
xpcom/base/CycleCollectedJSContext.h | 29 +++----------
9 files changed, 28 insertions(+), 144 deletions(-)
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp
index 7e103e2705d1..2973457ec3de 100644
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -15665,18 +15665,6 @@ nsAutoSyncOperation::~nsAutoSyncOperation() {
}
}
-void Document::SetIsInSyncOperation(bool aSync) {
- if (CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get()) {
- ccjs->UpdateMicroTaskSuppressionGeneration();
- }
-
- if (aSync) {
- ++mInSyncOperationCount;
- } else {
- --mInSyncOperationCount;
- }
-}
-
gfxUserFontSet* Document::GetUserFontSet() {
if (!mFontFaceSet) {
return nullptr;
diff --git a/dom/base/Document.h b/dom/base/Document.h
index c8de049526ea..7ef73651d47f 100644
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -3214,7 +3214,13 @@ class Document : public nsINode,
bool IsInSyncOperation() { return mInSyncOperationCount != 0; }
- void SetIsInSyncOperation(bool aSync);
+ void SetIsInSyncOperation(bool aSync) {
+ if (aSync) {
+ ++mInSyncOperationCount;
+ } else {
+ --mInSyncOperationCount;
+ }
+ }
bool CreatingStaticClone() const { return mCreatingStaticClone; }
diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini
index 06b5691422c5..e287a0d10ae8 100644
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -769,8 +769,6 @@ skip-if = debug == false
[test_shared_compartment2.html]
[test_structuredclone_backref.html]
[test_style_cssText.html]
-[test_suppressed_microtasks.html]
-skip-if = debug || asan || verify || toolkit == 'android' # The test needs to run reasonably fast.
[test_text_wholeText.html]
[test_textnode_normalize_in_selection.html]
[test_textnode_split_in_selection.html]
diff --git a/dom/base/test/test_suppressed_microtasks.html b/dom/base/test/test_suppressed_microtasks.html
deleted file mode 100644
index f5d333638698..000000000000
--- a/dom/base/test/test_suppressed_microtasks.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta charset="utf-8">
- <title>Test microtask suppression</title>
- <script src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
- <script>
- SimpleTest.waitForExplicitFinish();
-
- var previousTask = -1;
- function test() {
- let win = window.open("about:blank");
- win.onload = function() {
- win.onmessage = function() {
- win.start = win.performance.now();
- win.didRunMicrotask = false;
- win.onmessage = function() {
- ok(win.didRunMicrotask, "Should have run a microtask.");
- let period = win.performance.now() - win.start;
- win.opener.ok(
- period < 200,
- "Running a task should be fast. Took " + period + "ms.");
- win.onmessage = null;
- }
- win.queueMicrotask(function() { win.didRunMicrotask = true; });
- win.postMessage("measurementMessage", "*");
- }
- win.postMessage("initialMessage", "*");
-
- const last = 500000;
- for (let i = 0; i < last + 1; ++i) {
- window.queueMicrotask(function() {
- // Check that once microtasks are unsuppressed, they are handled in
- // the correct order.
- if (previousTask != i - 1) {
- // Explicitly optimize out cases which pass.
- ok(false, "Microtasks should be handled in order.");
- }
- previousTask = i;
- if (i == last) {
- win.close();
- SimpleTest.finish();
- }
- });
- }
-
- // Synchronous XMLHttpRequest suppresses microtasks.
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "slow.sjs", false);
- xhr.send();
- is(previousTask, -1, "Shouldn't have run microtasks during a sync XHR.");
- }
- }
- </script>
-</head>
-<body onload="test()">
-<p id="display"></p>
-<div id="content" style="display: none"></div>
-<pre id="test"></pre>
-</body>
-</html>
diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp
index c3e3f56834d7..3fda0a78fd23 100644
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -931,7 +931,7 @@ class WorkerJSContext final : public mozilla::CycleCollectedJSContext {
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(runnable);
- std::deque<RefPtr<MicroTaskRunnable>>* microTaskQueue = nullptr;
+ std::queue<RefPtr<MicroTaskRunnable>>* microTaskQueue = nullptr;
JSContext* cx = Context();
NS_ASSERTION(cx, "This should never be null!");
@@ -953,7 +953,7 @@ class WorkerJSContext final : public mozilla::CycleCollectedJSContext {
}
JS::JobQueueMayNotBeEmpty(cx);
- microTaskQueue->push_back(std::move(runnable));
+ microTaskQueue->push(std::move(runnable));
}
bool IsSystemCaller() const override {
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index 10099edc933e..af627f33d86d 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -4313,7 +4313,7 @@ void WorkerPrivate::EnterDebuggerEventLoop() {
{
MutexAutoLock lock(mMutex);
- std::deque<RefPtr<MicroTaskRunnable>>& debuggerMtQueue =
+ std::queue<RefPtr<MicroTaskRunnable>>& debuggerMtQueue =
ccjscx->GetDebuggerMicroTaskQueue();
while (mControlQueue.IsEmpty() &&
!(debuggerRunnablesPending = !mDebuggerQueue.IsEmpty()) &&
diff --git a/dom/worklet/WorkletThread.cpp b/dom/worklet/WorkletThread.cpp
index fae1a1c550d1..c672dfb21b8b 100644
--- a/dom/worklet/WorkletThread.cpp
+++ b/dom/worklet/WorkletThread.cpp
@@ -159,7 +159,7 @@ class WorkletJSContext final : public CycleCollectedJSContext {
#endif
JS::JobQueueMayNotBeEmpty(cx);
- GetMicroTaskQueue().push_back(std::move(runnable));
+ GetMicroTaskQueue().push(std::move(runnable));
}
bool IsSystemCaller() const override {
diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJSContext.cpp
index 0a35a5cf5524..347f15c82322 100644
--- a/xpcom/base/CycleCollectedJSContext.cpp
+++ b/xpcom/base/CycleCollectedJSContext.cpp
@@ -61,7 +61,6 @@ CycleCollectedJSContext::CycleCollectedJSContext()
mDoingStableStates(false),
mTargetedMicroTaskRecursionDepth(0),
mMicroTaskLevel(0),
- mSuppressionGeneration(0),
mDebuggerRecursionDepth(0),
mMicroTaskRecursionDepth(0),
mFinalizationRegistryCleanup(this) {
@@ -292,7 +291,7 @@ class CycleCollectedJSContext::SavedMicroTaskQueue
private:
CycleCollectedJSContext* ccjs;
- std::deque<RefPtr<MicroTaskRunnable>> mQueue;
+ std::queue<RefPtr<MicroTaskRunnable>> mQueue;
};
js::UniquePtr<JS::JobQueue::SavedJobQueue>
@@ -380,13 +379,13 @@ void CycleCollectedJSContext::SetPendingException(Exception* aException) {
mPendingException = aException;
}
-std::deque<RefPtr<MicroTaskRunnable>>&
+std::queue<RefPtr<MicroTaskRunnable>>&
CycleCollectedJSContext::GetMicroTaskQueue() {
MOZ_ASSERT(mJSContext);
return mPendingMicroTaskRunnables;
}
-std::deque<RefPtr<MicroTaskRunnable>>&
+std::queue<RefPtr<MicroTaskRunnable>>&
CycleCollectedJSContext::GetDebuggerMicroTaskQueue() {
MOZ_ASSERT(mJSContext);
return mDebuggerMicroTaskQueue;
@@ -563,7 +562,7 @@ void CycleCollectedJSContext::DispatchToMicroTask(
JS::JobQueueMayNotBeEmpty(Context());
LogMicroTaskRunnable::LogDispatch(runnable.get());
- mPendingMicroTaskRunnables.push_back(std::move(runnable));
+ mPendingMicroTaskRunnables.push(std::move(runnable));
}
class AsyncMutationHandler final : public mozilla::Runnable {
@@ -582,25 +581,6 @@ class AsyncMutationHandler final : public mozilla::Runnable {
}
};
-SuppressedMicroTasks::SuppressedMicroTasks(CycleCollectedJSContext* aContext)
- : mContext(aContext),
- mSuppressionGeneration(aContext->mSuppressionGeneration) {}
-
-bool SuppressedMicroTasks::Suppressed() {
- if (mSuppressionGeneration == mContext->mSuppressionGeneration) {
- return true;
- }
-
- for (std::deque<RefPtr<MicroTaskRunnable>>::reverse_iterator it =
- mSuppressedMicroTaskRunnables.rbegin();
- it != mSuppressedMicroTaskRunnables.rend(); ++it) {
- mContext->GetMicroTaskQueue().push_front(*it);
- }
- mContext->mSuppressedMicroTasks = nullptr;
-
- return false;
-}
-
bool CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool aForce) {
if (mPendingMicroTaskRunnables.empty() && mDebuggerMicroTaskQueue.empty()) {
AfterProcessMicrotasks();
@@ -636,14 +616,15 @@ bool CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool aForce) {
bool didProcess = false;
AutoSlowOperation aso;
+ std::queue<RefPtr<MicroTaskRunnable>> suppressed;
for (;;) {
RefPtr<MicroTaskRunnable> runnable;
if (!mDebuggerMicroTaskQueue.empty()) {
runnable = std::move(mDebuggerMicroTaskQueue.front());
- mDebuggerMicroTaskQueue.pop_front();
+ mDebuggerMicroTaskQueue.pop();
} else if (!mPendingMicroTaskRunnables.empty()) {
runnable = std::move(mPendingMicroTaskRunnables.front());
- mPendingMicroTaskRunnables.pop_front();
+ mPendingMicroTaskRunnables.pop();
} else {
break;
}
@@ -654,16 +635,10 @@ bool CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool aForce) {
// all suppressed tasks in mDebuggerMicroTaskQueue unexpectedly.
MOZ_ASSERT(NS_IsMainThread());
JS::JobQueueMayNotBeEmpty(Context());
- if (runnable != mSuppressedMicroTasks) {
- if (!mSuppressedMicroTasks) {
- mSuppressedMicroTasks = new SuppressedMicroTasks(this);
- }
- mSuppressedMicroTasks->mSuppressedMicroTaskRunnables.push_back(
- runnable);
- }
+ suppressed.push(runnable);
} else {
if (mPendingMicroTaskRunnables.empty() &&
- mDebuggerMicroTaskQueue.empty() && !mSuppressedMicroTasks) {
+ mDebuggerMicroTaskQueue.empty() && suppressed.empty()) {
JS::JobQueueIsEmpty(Context());
}
didProcess = true;
@@ -678,9 +653,7 @@ bool CycleCollectedJSContext::PerformMicroTaskCheckPoint(bool aForce) {
// Note, it is possible that we end up keeping these suppressed tasks around
// for some time, but no longer than spinning the event loop nestedly
// (sync XHR, alert, etc.)
- if (mSuppressedMicroTasks) {
- mPendingMicroTaskRunnables.push_back(mSuppressedMicroTasks);
- }
+ mPendingMicroTaskRunnables.swap(suppressed);
AfterProcessMicrotasks();
@@ -695,7 +668,7 @@ void CycleCollectedJSContext::PerformDebuggerMicroTaskCheckpoint() {
for (;;) {
// For a debugger microtask checkpoint, we always use the debugger microtask
// queue.
- std::deque<RefPtr<MicroTaskRunnable>>* microtaskQueue =
+ std::queue<RefPtr<MicroTaskRunnable>>* microtaskQueue =
&GetDebuggerMicroTaskQueue();
if (microtaskQueue->empty()) {
@@ -708,7 +681,7 @@ void CycleCollectedJSContext::PerformDebuggerMicroTaskCheckpoint() {
LogMicroTaskRunnable::Run log(runnable.get());
// This function can re-enter, so we remove the element before calling.
- microtaskQueue->pop_front();
+ microtaskQueue->pop();
if (mPendingMicroTaskRunnables.empty() && mDebuggerMicroTaskQueue.empty()) {
JS::JobQueueIsEmpty(Context());
diff --git a/xpcom/base/CycleCollectedJSContext.h b/xpcom/base/CycleCollectedJSContext.h
index 116bff1c90c8..769b000418ab 100644
--- a/xpcom/base/CycleCollectedJSContext.h
+++ b/xpcom/base/CycleCollectedJSContext.h
@@ -7,7 +7,7 @@
#ifndef mozilla_CycleCollectedJSContext_h
#define mozilla_CycleCollectedJSContext_h
-#include <deque>
+#include <queue>
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
@@ -81,20 +81,6 @@ class MicroTaskRunnable {
virtual ~MicroTaskRunnable() = default;
};
-// Store the suppressed mictotasks in another microtask so that operations
-// for the microtask queue as a whole keep working.
-class SuppressedMicroTasks : public MicroTaskRunnable {
- public:
- explicit SuppressedMicroTasks(CycleCollectedJSContext* aContext);
-
- MOZ_CAN_RUN_SCRIPT_BOUNDARY void Run(AutoSlowOperation& aAso) final {}
- virtual bool Suppressed();
-
- CycleCollectedJSContext* mContext;
- uint64_t mSuppressionGeneration;
- std::deque<RefPtr<MicroTaskRunnable>> mSuppressedMicroTaskRunnables;
-};
-
// Support for JS FinalizationRegistry objects, which allow a JS callback to be
// registered that is called when objects die.
//
@@ -131,7 +117,6 @@ class FinalizationRegistryCleanup {
class CycleCollectedJSContext : dom::PerThreadAtomCache, private JS::JobQueue {
friend class CycleCollectedJSRuntime;
- friend class SuppressedMicroTasks;
protected:
CycleCollectedJSContext();
@@ -181,8 +166,8 @@ class CycleCollectedJSContext : dom::PerThreadAtomCache, private JS::JobQueue {
already_AddRefed<dom::Exception> GetPendingException() const;
void SetPendingException(dom::Exception* aException);
- std::deque<RefPtr<MicroTaskRunnable>>& GetMicroTaskQueue();
- std::deque<RefPtr<MicroTaskRunnable>>& GetDebuggerMicroTaskQueue();
+ std::queue<RefPtr<MicroTaskRunnable>>& GetMicroTaskQueue();
+ std::queue<RefPtr<MicroTaskRunnable>>& GetDebuggerMicroTaskQueue();
JSContext* Context() const {
MOZ_ASSERT(mJSContext);
@@ -198,8 +183,6 @@ class CycleCollectedJSContext : dom::PerThreadAtomCache, private JS::JobQueue {
mTargetedMicroTaskRecursionDepth = aDepth;
}
- void UpdateMicroTaskSuppressionGeneration() { ++mSuppressionGeneration; }
-
protected:
JSContext* MaybeContext() const { return mJSContext; }
@@ -333,10 +316,8 @@ class CycleCollectedJSContext : dom::PerThreadAtomCache, private JS::JobQueue {
uint32_t mMicroTaskLevel;
- std::deque<RefPtr<MicroTaskRunnable>> mPendingMicroTaskRunnables;
- std::deque<RefPtr<MicroTaskRunnable>> mDebuggerMicroTaskQueue;
- RefPtr<SuppressedMicroTasks> mSuppressedMicroTasks;
- uint64_t mSuppressionGeneration;
+ std::queue<RefPtr<MicroTaskRunnable>> mPendingMicroTaskRunnables;
+ std::queue<RefPtr<MicroTaskRunnable>> mDebuggerMicroTaskQueue;
// How many times the debugger has interrupted execution, possibly creating
// microtask checkpoints in places that they would not normally occur.
1
0
[tor-browser-build/master] Revert "Bug 40383: Workaround issue in https-e wasm"
by boklm@torproject.org 07 Dec '21
by boklm@torproject.org 07 Dec '21
07 Dec '21
commit f8a2f0ca796de7cc9a0deec2e1379bf8b7936075
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Dec 7 16:23:12 2021 +0000
Revert "Bug 40383: Workaround issue in https-e wasm"
This reverts commit 818acaeca3b3ecb2584c0bf1683d0b0d9a328e09.
Closes: #40389.
---
...01-Bug-40383-Disable-https-e-wasm-ruleset.patch | 26 ----------------------
projects/https-everywhere/build | 5 -----
projects/https-everywhere/config | 2 --
3 files changed, 33 deletions(-)
diff --git a/projects/https-everywhere/0001-Bug-40383-Disable-https-e-wasm-ruleset.patch b/projects/https-everywhere/0001-Bug-40383-Disable-https-e-wasm-ruleset.patch
deleted file mode 100644
index 87befad..0000000
--- a/projects/https-everywhere/0001-Bug-40383-Disable-https-e-wasm-ruleset.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 647aa186351f7a6ee6050e0a3a2bde7ccf5a8192 Mon Sep 17 00:00:00 2001
-From: Matthew Finkel <sysrqb(a)torproject.org>
-Date: Wed, 10 Nov 2021 20:00:18 +0000
-Subject: [PATCH] Bug 40383: Disable https-e wasm ruleset
-
----
- chromium/background-scripts/rules.js | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/chromium/background-scripts/rules.js b/chromium/background-scripts/rules.js
-index 7f0a5b5506..55a3f75094 100644
---- a/chromium/background-scripts/rules.js
-+++ b/chromium/background-scripts/rules.js
-@@ -216,7 +216,8 @@ RuleSets.prototype = {
- this.store = store;
- this.ruleActiveStates = await this.store.get_promise('ruleActiveStates', {});
- try {
-- this.wasm_rs = wasm.RuleSets.new();
-+ // Bug 40383: Disable wasm ruleset for now.
-+ //this.wasm_rs = wasm.RuleSets.new();
- } catch(e) {
- util.log(util.WARN, 'Falling back to pure JS implementation: ' + e);
- }
---
-2.25.1
-
diff --git a/projects/https-everywhere/build b/projects/https-everywhere/build
index 4719fd6..10dd4bf 100644
--- a/projects/https-everywhere/build
+++ b/projects/https-everywhere/build
@@ -2,11 +2,6 @@
[% c("var/set_default_env") -%]
tar xf [% project %]-[% c('version') %].tar.gz
cd [% project %]-[% c('version') %]
-
-[% IF c("var/windows") %]
- patch -p1 < $rootdir/0001-Bug-40383-Disable-https-e-wasm-ruleset.patch
-[% END -%]
-
./make.sh
# Since 5.0.2 a .xpi for AMO is built, too. We don't need it.
rm pkg/*-amo.xpi
diff --git a/projects/https-everywhere/config b/projects/https-everywhere/config
index 012680a..9af5ff6 100644
--- a/projects/https-everywhere/config
+++ b/projects/https-everywhere/config
@@ -33,5 +33,3 @@ var:
input_files:
- project: container-image
- - filename: 0001-Bug-40383-Disable-https-e-wasm-ruleset.patch
- enable: '[% c("var/windows") %]'
1
0
[tor-browser/tor-browser-91.4.0esr-11.5-1] Revert "Bug 40475: Include clearing CORS preflight cache"
by gk@torproject.org 07 Dec '21
by gk@torproject.org 07 Dec '21
07 Dec '21
commit 492873055db358d6d32d86ea31b3bc910c186b4f
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Dec 7 11:56:08 2021 +0000
Revert "Bug 40475: Include clearing CORS preflight cache"
This reverts commit 0695c7c0ee83a1ec69b198f50fe3b2ee2514154f.
Fixes: tor-browser#40475.
---
netwerk/protocol/http/nsCORSListenerProxy.cpp | 7 -------
netwerk/protocol/http/nsCORSListenerProxy.h | 1 -
netwerk/protocol/http/nsHttpHandler.cpp | 1 -
3 files changed, 9 deletions(-)
diff --git a/netwerk/protocol/http/nsCORSListenerProxy.cpp b/netwerk/protocol/http/nsCORSListenerProxy.cpp
index 9ece2020bc7d..1de4e2abed4a 100644
--- a/netwerk/protocol/http/nsCORSListenerProxy.cpp
+++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp
@@ -358,13 +358,6 @@ void nsCORSListenerProxy::ClearCache() {
sPreflightCache->Clear();
}
-/* static */
-void nsCORSListenerProxy::Clear() {
- if (sPreflightCache) {
- sPreflightCache->Clear();
- }
-}
-
nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
bool aWithCredentials)
diff --git a/netwerk/protocol/http/nsCORSListenerProxy.h b/netwerk/protocol/http/nsCORSListenerProxy.h
index 5b858223028f..e3f1ff27f1d1 100644
--- a/netwerk/protocol/http/nsCORSListenerProxy.h
+++ b/netwerk/protocol/http/nsCORSListenerProxy.h
@@ -59,7 +59,6 @@ class nsCORSListenerProxy final : public nsIStreamListener,
static void Shutdown();
static void ClearCache();
- static void Clear();
[[nodiscard]] nsresult Init(nsIChannel* aChannel,
DataURIHandling aAllowDataURI);
diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp
index 5925c4598bc1..0bb944164652 100644
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -2167,7 +2167,6 @@ nsHttpHandler::Observe(nsISupports* subject, const char* topic,
if (mAltSvcCache) {
mAltSvcCache->ClearAltServiceMappings();
}
- nsCORSListenerProxy::Clear();
} else if (!strcmp(topic, NS_NETWORK_LINK_TOPIC)) {
nsAutoCString converted = NS_ConvertUTF16toUTF8(data);
if (!strcmp(converted.get(), NS_NETWORK_LINK_DATA_CHANGED)) {
1
0
[tor-browser/tor-browser-91.4.0esr-11.5-1] fixup! Bug 10760: Integrate TorButton to TorBrowser core
by gk@torproject.org 07 Dec '21
by gk@torproject.org 07 Dec '21
07 Dec '21
commit 0bbf9017fe3888a9ad2e1df50cc2bfde1e101762
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Dec 7 11:46:13 2021 +0000
fixup! Bug 10760: Integrate TorButton to TorBrowser core
---
toolkit/torproject/torbutton | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton
index 5807ed682fa9..acb4d4aad725 160000
--- a/toolkit/torproject/torbutton
+++ b/toolkit/torproject/torbutton
@@ -1 +1 @@
-Subproject commit 5807ed682fa94f2f54e40bb9b57a871a252f35df
+Subproject commit acb4d4aad7252b627ea4d1bddc560b524939942f
1
0
commit acb4d4aad7252b627ea4d1bddc560b524939942f
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Dec 7 11:44:07 2021 +0000
Translations update
---
chrome/locale/ar/torbutton.dtd | 1 +
chrome/locale/bn-BD/torbutton.dtd | 1 +
chrome/locale/bn-BD/torbutton.properties | 30 ++---
chrome/locale/ca/aboutTor.dtd | 2 +-
chrome/locale/ca/torbutton.dtd | 1 +
chrome/locale/cs/aboutTor.dtd | 6 +-
chrome/locale/cs/torbutton.dtd | 1 +
chrome/locale/da/torbutton.dtd | 1 +
chrome/locale/da/torbutton.properties | 22 ++--
chrome/locale/de/aboutTor.dtd | 2 +-
chrome/locale/de/torbutton.dtd | 1 +
chrome/locale/el/aboutTBUpdate.dtd | 2 +-
chrome/locale/el/aboutTor.dtd | 2 +-
chrome/locale/el/browserOnboarding.properties | 22 ++--
chrome/locale/el/torbutton.dtd | 1 +
chrome/locale/el/torbutton.properties | 26 ++---
chrome/locale/es-AR/aboutTor.dtd | 2 +-
chrome/locale/es-AR/torbutton.dtd | 1 +
chrome/locale/es-ES/torbutton.dtd | 3 +-
chrome/locale/es-ES/torbutton.properties | 78 ++++++-------
chrome/locale/eu/torbutton.dtd | 1 +
chrome/locale/fa/torbutton.dtd | 1 +
chrome/locale/fa/torbutton.properties | 26 ++---
chrome/locale/fr/aboutTor.dtd | 2 +-
chrome/locale/fr/torbutton.dtd | 1 +
chrome/locale/ga-IE/torbutton.dtd | 1 +
chrome/locale/he/torbutton.dtd | 1 +
chrome/locale/hu/torbutton.dtd | 1 +
chrome/locale/hu/torbutton.properties | 20 ++--
chrome/locale/id/aboutTor.dtd | 2 +-
chrome/locale/id/torbutton.dtd | 1 +
chrome/locale/id/torbutton.properties | 152 +++++++++++++-------------
chrome/locale/is/torbutton.dtd | 1 +
chrome/locale/it/aboutTor.dtd | 2 +-
chrome/locale/it/torbutton.dtd | 1 +
chrome/locale/it/torbutton.properties | 6 +-
chrome/locale/ja/aboutTor.dtd | 4 +-
chrome/locale/ja/torbutton.dtd | 1 +
chrome/locale/ja/torbutton.properties | 8 +-
chrome/locale/ka/aboutTor.dtd | 10 +-
chrome/locale/ka/browserOnboarding.properties | 6 +-
chrome/locale/ka/torbutton.dtd | 1 +
chrome/locale/ka/torbutton.properties | 2 +-
chrome/locale/ko/torbutton.dtd | 1 +
chrome/locale/lt/aboutTor.dtd | 4 +-
chrome/locale/lt/torbutton.dtd | 1 +
chrome/locale/lt/torbutton.properties | 36 +++---
chrome/locale/mk/aboutTor.dtd | 4 +-
chrome/locale/mk/torbutton.dtd | 1 +
chrome/locale/ms/torbutton.dtd | 1 +
chrome/locale/my/torbutton.dtd | 1 +
chrome/locale/nb-NO/torbutton.dtd | 1 +
chrome/locale/nb-NO/torbutton.properties | 4 +-
chrome/locale/nl/torbutton.dtd | 1 +
chrome/locale/nl/torbutton.properties | 10 +-
chrome/locale/pl/aboutTor.dtd | 2 +-
chrome/locale/pl/torbutton.dtd | 1 +
chrome/locale/pt-BR/aboutTor.dtd | 2 +-
chrome/locale/pt-BR/torbutton.dtd | 1 +
chrome/locale/ro/aboutTor.dtd | 2 +-
chrome/locale/ro/torbutton.dtd | 1 +
chrome/locale/ro/torbutton.properties | 22 ++--
chrome/locale/ru/aboutTor.dtd | 2 +-
chrome/locale/ru/torbutton.dtd | 1 +
chrome/locale/sv-SE/aboutDialog.dtd | 2 +-
chrome/locale/sv-SE/aboutTor.dtd | 6 +-
chrome/locale/sv-SE/brand.dtd | 4 +-
chrome/locale/sv-SE/brand.properties | 2 +-
chrome/locale/sv-SE/branding/brand.ftl | 4 +-
chrome/locale/sv-SE/torbutton.dtd | 1 +
chrome/locale/sv-SE/torbutton.properties | 8 +-
chrome/locale/th/browserOnboarding.properties | 2 +-
chrome/locale/th/torbutton.dtd | 1 +
chrome/locale/tr/aboutTBUpdate.dtd | 4 +-
chrome/locale/tr/aboutTor.dtd | 6 +-
chrome/locale/tr/torbutton.dtd | 1 +
chrome/locale/vi/torbutton.dtd | 1 +
chrome/locale/zh-CN/aboutTor.dtd | 2 +-
chrome/locale/zh-CN/torbutton.dtd | 1 +
chrome/locale/zh-TW/aboutTor.dtd | 2 +-
chrome/locale/zh-TW/torbutton.dtd | 1 +
81 files changed, 320 insertions(+), 283 deletions(-)
diff --git a/chrome/locale/ar/torbutton.dtd b/chrome/locale/ar/torbutton.dtd
index c5f101e5..e006764c 100644
--- a/chrome/locale/ar/torbutton.dtd
+++ b/chrome/locale/ar/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "تفضيلاتك الخاصة للمتصفح تسببت في إعدادات أمان غير معتادة. لأمان وخصوصية أفضل ننصح باستخدام أحد مستويات الأمان المبدئية.">
<!ENTITY torbutton.prefs.sec_restore_defaults "استعد الإعادات المبدئية">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "إعدادات الأمن المتقدمة ...">
+<!ENTITY torbutton.prefs.sec_change "تبديل…">
<!ENTITY torbutton.circuit_display.title "دائرة تور">
<!ENTITY torbutton.circuit_display.new_circuit "دائرة تور جديدة لهذا الموقع">
diff --git a/chrome/locale/bn-BD/torbutton.dtd b/chrome/locale/bn-BD/torbutton.dtd
index 6e01a3f2..f9f4aa31 100644
--- a/chrome/locale/bn-BD/torbutton.dtd
+++ b/chrome/locale/bn-BD/torbutton.dtd
@@ -46,6 +46,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "আপনার কাস্টম ব্রাউজারের পছন্দগুলির কারণে অস্বাভাবিক নিরাপত্তা সেটিংস দেখা দিয়েছে নিরাপত্তা এবং গোপনীয়তার কারণে, আমরা আপনাকে ডিফল্ট নিরাপত্তা স্তরগুলির একটি চয়ন করার সুপারিশ করি।">
<!ENTITY torbutton.prefs.sec_restore_defaults "স্বয়ংক্রিয় সেটিংসগুলি পুনঃস্থাপন করুন">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "উন্নত নিরাপত্তা সেটিংস ...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "টর সার্কিট">
<!ENTITY torbutton.circuit_display.new_circuit "এই সাইটের জন্য নতুন সার্কিট">
diff --git a/chrome/locale/bn-BD/torbutton.properties b/chrome/locale/bn-BD/torbutton.properties
index 02b68434..bef22f3c 100644
--- a/chrome/locale/bn-BD/torbutton.properties
+++ b/chrome/locale/bn-BD/torbutton.properties
@@ -72,12 +72,12 @@ onionServices.descNotFound=সবচেয়ে বড় সম্ভাবনা
onionServices.descNotFound.longDescription=Details: %S — The requested onion service descriptor can't be found on the hashring and therefore the service is not reachable by the client.
# Tor SOCKS error 0xF1:
onionServices.descInvalid.pageTitle=অনিওনসাইট লোড করতে সমস্যা
-onionServices.descInvalid.header=Onionsite Cannot Be Reached
-onionServices.descInvalid=The onionsite is unreachable due an internal error.
+onionServices.descInvalid.header=অনিয়ন সাইটে পৌছানো যাচ্ছে না
+onionServices.descInvalid=অন্তর্বর্তী ত্রুটির জন্য অনিয়ন সাইটে পৌছানো যাচ্ছে না।
onionServices.descInvalid.longDescription=Details: %S — The requested onion service descriptor can't be parsed or signature validation failed.
# Tor SOCKS error 0xF2:
onionServices.introFailed.pageTitle=অনিওনসাইট লোড করতে সমস্যা
-onionServices.introFailed.header=Onionsite Has Disconnected
+onionServices.introFailed.header=অনিয়ন সাইট বিযুক্ত হয়েছে
onionServices.introFailed=সবচেয়ে বড় সম্ভাবনা হচ্ছে অনিয়নসাইটটি তারহীন(অফলাইন)। অনিয়নসাইট প্রশাসকের সাথে যোগাযোগ করো।
onionServices.introFailed.longDescription=Details: %S — Introduction failed, which means that the descriptor was found but the service is no longer connected to the introduction point. It is likely that the service has changed its descriptor or that it is not running.
# Tor SOCKS error 0xF3:
@@ -86,23 +86,23 @@ onionServices.rendezvousFailed.header=Unable to Connect to Onionsite
onionServices.rendezvousFailed=The onionsite is busy or the Tor network is overloaded. Try again later.
onionServices.rendezvousFailed.longDescription=Details: %S — The client failed to rendezvous with the service, which means that the client was unable to finalize the connection.
# Tor SOCKS error 0xF4:
-onionServices.clientAuthMissing.pageTitle=Authorization Required
-onionServices.clientAuthMissing.header=Onionsite Requires Authentication
+onionServices.clientAuthMissing.pageTitle=যাচাইকরণ প্রয়োজন
+onionServices.clientAuthMissing.header=অনিয়ন সাইটে যাচাইকরণ প্রয়োজন
onionServices.clientAuthMissing=Access to the onionsite requires a key but none was provided.
onionServices.clientAuthMissing.longDescription=Details: %S — The client downloaded the requested onion service descriptor but was unable to decrypt its content because client authorization information is missing.
# Tor SOCKS error 0xF5:
-onionServices.clientAuthIncorrect.pageTitle=Authorization Failed
-onionServices.clientAuthIncorrect.header=Onionsite Authentication Failed
-onionServices.clientAuthIncorrect=The provided key is incorrect or has been revoked. Contact the onionsite administrator.
+onionServices.clientAuthIncorrect.pageTitle=যাচাইকরণ ব্যর্থ
+onionServices.clientAuthIncorrect.header=অনিয়ন সাইট যাচাইকরণ ব্যর্থ
+onionServices.clientAuthIncorrect=প্রদত্ত চাবি ভুল অথবা রদ করা হয়েছে। অনিয়ন সাইট ব্যবস্থাপককে যোগাযোগ করো।
onionServices.clientAuthIncorrect.longDescription=Details: %S — The client was able to download the requested onion service descriptor but was unable to decrypt its content using the provided client authorization information. This may mean that access has been revoked.
# Tor SOCKS error 0xF6:
onionServices.badAddress.pageTitle=অনিওনসাইট লোড করতে সমস্যা
-onionServices.badAddress.header=Invalid Onionsite Address
+onionServices.badAddress.header=ভুল অনিয়ন সাইট ঠিকানা
onionServices.badAddress=The provided onionsite address is invalid. Please check that you entered it correctly.
onionServices.badAddress.longDescription=Details: %S — The provided .onion address is invalid. This error is returned due to one of the following reasons: the address checksum doesn't match, the ed25519 public key is invalid, or the encoding is invalid.
# Tor SOCKS error 0xF7:
onionServices.introTimedOut.pageTitle=অনিওনসাইট লোড করতে সমস্যা
-onionServices.introTimedOut.header=Onionsite Circuit Creation Timed Out
+onionServices.introTimedOut.header=অনিয়ন সাইট বর্তনী তৈরির সময় শেষ হয়ে গেছে
onionServices.introTimedOut=Failed to connect to the onionsite, possibly due to a poor network connection.
onionServices.introTimedOut.longDescription=Details: %S — The connection to the requested onion service timed out while trying to build the rendezvous circuit.
#
@@ -138,11 +138,11 @@ onionLocation.notNow=এখন না
onionLocation.notNowAccessKey=n
onionLocation.description=There's a more private and secure version of this site available over the Tor network via onion services. Onion services help website publishers and their visitors defeat surveillance and censorship.
onionLocation.tryThis=Try Onion Services
-onionLocation.onionAvailable=.onion available
-onionLocation.learnMore=Learn more…
-onionLocation.always=Always
-onionLocation.askEverytime=Ask every time
-onionLocation.prioritizeOnionsDescription=Prioritize .onion sites when known.
+onionLocation.onionAvailable=.onion আছে
+onionLocation.learnMore=আরো জানো...
+onionLocation.always=সর্বদা
+onionLocation.askEverytime=প্রত্যেকবার জিজ্ঞাসা করো
+onionLocation.prioritizeOnionsDescription=পাওয়া গেলে .onion সেবাকে অধিক গুরুত্ব দাও।
onionLocation.onionServicesTitle=ওনিওন সেবা
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
diff --git a/chrome/locale/ca/aboutTor.dtd b/chrome/locale/ca/aboutTor.dtd
index a566a3a9..db8d2753 100644
--- a/chrome/locale/ca/aboutTor.dtd
+++ b/chrome/locale/ca/aboutTor.dtd
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Your donation will be matched by Friends of Tor, up to $150,000.">
+<!ENTITY aboutTor.yec.donationMatch "Amics del Tor igualarà la vostra donació fins a 150.000 dòlars.">
diff --git a/chrome/locale/ca/torbutton.dtd b/chrome/locale/ca/torbutton.dtd
index ac50edc5..fdd725cf 100644
--- a/chrome/locale/ca/torbutton.dtd
+++ b/chrome/locale/ca/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Les preferències personalitzades del navegador que heu triat fan que la configuració de seguretat sigui poc habitual. Per raons de privadesa i seguretat, recomanem que trieu un nivell de seguretat per defecte.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Restaura els valors per defecte">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Configuració de seguretat avançada…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Circuit de Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Circuit nou per a aquest lloc">
diff --git a/chrome/locale/cs/aboutTor.dtd b/chrome/locale/cs/aboutTor.dtd
index 2d5dd753..eaddc377 100644
--- a/chrome/locale/cs/aboutTor.dtd
+++ b/chrome/locale/cs/aboutTor.dtd
@@ -27,7 +27,7 @@
<!ENTITY aboutTor.newsletter.tagline "Nechte si posílat nejnovější informace o Toru.">
<!ENTITY aboutTor.newsletter.link_text "Přihlaste se k odběru zpravodaje Toru.">
-<!ENTITY aboutTor.donationBanner.freeToUse "Tor je zdarma k použití díky darům od lidí jako ty.">
+<!ENTITY aboutTor.donationBanner.freeToUse "Tor je zdarma k použití díky darům od lidí jako jste vy.">
<!ENTITY aboutTor.donationBanner.buttonA "Přispějte">
<!-- Year end campaign strings -->
@@ -47,8 +47,8 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
-<!ENTITY aboutTor.yec.motto "Soukromí je lidksé právo">
+<!ENTITY aboutTor.yec.slogan "RUCE\nPRYČ\nOD\nMÝCH\nDAT">
+<!ENTITY aboutTor.yec.motto "Soukromí je lidské právo">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/cs/torbutton.dtd b/chrome/locale/cs/torbutton.dtd
index d273f72b..b13f7e09 100644
--- a/chrome/locale/cs/torbutton.dtd
+++ b/chrome/locale/cs/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Vaše nastavení prohlížeče neodpovídá standardnímu nastavení zabezpečení. Z důvodu ochrany soukromí a zvýšení bezpečnosti vám doporučujeme vybrat si jednu z výchozích bezpečnostních úrovní.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Obnovit výchozí">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Rozšířená bezpečnostní nastavení…">
+<!ENTITY torbutton.prefs.sec_change "Změnit...">
<!ENTITY torbutton.circuit_display.title "Řetězec sítí Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Nový řetězec sítí Tor k této stránce">
diff --git a/chrome/locale/da/torbutton.dtd b/chrome/locale/da/torbutton.dtd
index 6a4fb8aa..3661da53 100644
--- a/chrome/locale/da/torbutton.dtd
+++ b/chrome/locale/da/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Dine tilpassede browserpræferencer har resulterede i usædvanlige sikkerhedsindstillinger. Pga. sikkerheds- og privatlivsårsagen, anbefaler vi at du vælger en af standardsikkerhedsniveauerne.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Gendan standarder">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Avancerede sikkerhedsindstillinger…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor-kredsløb">
<!ENTITY torbutton.circuit_display.new_circuit "Nyt kredsløb til dette sted">
diff --git a/chrome/locale/da/torbutton.properties b/chrome/locale/da/torbutton.properties
index 9de61c83..6b2a7062 100644
--- a/chrome/locale/da/torbutton.properties
+++ b/chrome/locale/da/torbutton.properties
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=Fjern
onionServices.authPreferences.removeAll=Fjern alle
onionServices.authPreferences.failedToGetKeys=Kan ikke hente nøgler fra tor
onionServices.authPreferences.failedToRemoveKey=Kan ikke fjerne nøgle
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=Dette onionsted vil snart være uopnåelig. Venligst kontakt stedets administrator og anbefal at de opgraderer.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
-onionServices.v2Deprecated.tryAgain=Got it
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.pageTitle=Advarsel om V2-onionsteder som udgår
+onionServices.v2Deprecated.header=Version 2-onionsteder udgår snart
+onionServices.v2Deprecated=Onionstedet vil snart ikke være tilgængeligt. Kontakt venligst stedets administrator og opforder dem at opgradere.
+onionServices.v2Deprecated.longDescription=Tor slutter sin understøttelse af version 2-oniontjenester fra Juli 2021 og onionstedet vil ikke længere kunne tilgås fra denne adresse. Hvis du er stedets administator, så opgrader til en version 3-oniontjeneste snart.
+onionServices.v2Deprecated.tryAgain=Okay
+onionServices.v2Deprecated.tooltip=Onionstedet kan snart ikke tilgås
# Onion-Location strings.
onionLocation.alwaysPrioritize=Prioriter altid onions
@@ -146,11 +146,11 @@ onionLocation.prioritizeOnionsDescription=Prioriter .onion-steder når de kendes
onionLocation.onionServicesTitle=Oniontjenester
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
-cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
-cryptoSafetyPrompt.whatCanHeading=What can you do about it?
-cryptoSafetyPrompt.whatCanBody=You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning.
+cryptoSafetyPrompt.cryptoWarning=En kryptovalutaadresse (%S) er blevet kopieret fra et usikkert websted. Den kan være blevet ændret.
+cryptoSafetyPrompt.whatCanHeading=Hvad kan du gøre ved det?
+cryptoSafetyPrompt.whatCanBody=Du kan prøve at oprette forbindelse igen med et nyt kredsløb for at etablere en sikker forbindelse eller acceptere risikoen og se bort fra advarslen.
cryptoSafetyPrompt.learnMore=Lær mere
-cryptoSafetyPrompt.primaryAction=Reload Tab with a New Circuit
+cryptoSafetyPrompt.primaryAction=Genindlæs faneblad med et nyt kredsløb
cryptoSafetyPrompt.primaryActionAccessKey=B
-cryptoSafetyPrompt.secondaryAction=Dismiss Warning
+cryptoSafetyPrompt.secondaryAction=Se bort fra advarsel
cryptoSafetyPrompt.secondaryActionAccessKey=B
diff --git a/chrome/locale/de/aboutTor.dtd b/chrome/locale/de/aboutTor.dtd
index 05c71121..b602df14 100644
--- a/chrome/locale/de/aboutTor.dtd
+++ b/chrome/locale/de/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "HÄNDE\nWEG\nVON MEINEN\nDATEN">
<!ENTITY aboutTor.yec.motto "Datenschutz ist ein Menschenrecht">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/de/torbutton.dtd b/chrome/locale/de/torbutton.dtd
index 86266aa5..4f1b5734 100644
--- a/chrome/locale/de/torbutton.dtd
+++ b/chrome/locale/de/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Ihre benutzerdefinierten Browser-Einstellungen haben zu ungewöhnlichen Sicherheitseinstellungen geführt. Aus Gründen der Sicherheit und Privatsphäre empfehlen wir dir eine der vorgegebenen Sicherheitsstufen auszuwählen.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Standardeinstellungen wiederherstellen">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Erweiterte Sicherheitseinstellungen …">
+<!ENTITY torbutton.prefs.sec_change "Ändern...">
<!ENTITY torbutton.circuit_display.title "Tor Kanal">
<!ENTITY torbutton.circuit_display.new_circuit "Neuen Kanal für diese Seite">
diff --git a/chrome/locale/el/aboutTBUpdate.dtd b/chrome/locale/el/aboutTBUpdate.dtd
index ae3b1020..1a8619d9 100644
--- a/chrome/locale/el/aboutTBUpdate.dtd
+++ b/chrome/locale/el/aboutTBUpdate.dtd
@@ -1,6 +1,6 @@
<!ENTITY aboutTBUpdate.changelogTitle "Αρχείο αλλαγών του Tor Browser">
<!ENTITY aboutTBUpdate.updated "Ο Tor Browser αναβαθμίστηκε.">
-<!ENTITY aboutTBUpdate.linkPrefix "Για τις πιο πρόσφατες πληροφορίες για αυτή την έκδοση,">
+<!ENTITY aboutTBUpdate.linkPrefix "Για τις πιο πρόσφατες πληροφορίες για αυτή την έκδοση, ">
<!ENTITY aboutTBUpdate.linkLabel "επισκεφθείτε την ιστοσελίδα μας">
<!ENTITY aboutTBUpdate.linkSuffix ".">
<!ENTITY aboutTBUpdate.version "Έκδοση">
diff --git a/chrome/locale/el/aboutTor.dtd b/chrome/locale/el/aboutTor.dtd
index a162ceaa..43179324 100644
--- a/chrome/locale/el/aboutTor.dtd
+++ b/chrome/locale/el/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "ΚΑΤΩ ΤΑ\nΧΕΡΙΑ\nΑΠΟ ΤΑ\nΔΕΔΟΜΕΝΑ ΜΟΥ">
<!ENTITY aboutTor.yec.motto "Η ιδιωτικότητα είναι ανθρώπινο δικαίωμα ">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/el/browserOnboarding.properties b/chrome/locale/el/browserOnboarding.properties
index e466aefe..552863f0 100644
--- a/chrome/locale/el/browserOnboarding.properties
+++ b/chrome/locale/el/browserOnboarding.properties
@@ -5,9 +5,9 @@
onboarding.tour-tor-welcome=Καλώς ήλθατε
onboarding.tour-tor-welcome.title=Είστε έτοιμος.
onboarding.tour-tor-welcome.description=Ο Tor Browser προσφέρει τα υψηλότερα στάνταρ στην ιδιωτικότητα και την ασφάλεια κατά την περιήγηση στο διαδίκτυο. Τώρα είστε προστατευμένος από τον εντοπισμό, την κατασκοπία και τη λογοκρισία. Μία γρήγορη δοκιμή θα σας δείξει πώς.
-onboarding.tour-tor-welcome.next-button=Πηγαίνετε στην Ιδιωτικότητα
+onboarding.tour-tor-welcome.next-button=Πάμε στην Ιδιωτικότητα
-onboarding.tour-tor-privacy=Απόρρητο
+onboarding.tour-tor-privacy=Ιδιωτικότητα
onboarding.tour-tor-privacy.title=Αποφύγετε εντοπιστές και αδιάκριτους.
onboarding.tour-tor-privacy.description=Ο Tor Browser απομονώνει τα cookies και διαγράφει το ιστορικό περιήγησης μόλις κλείσετε την καρτέλα σας. Αυτές οι ρυθμίσεις που εξασφαλίζουν την ιδιωτικότητά σας και την ασφάλειά σας είναι αποθηκευμένες στον περιηγητή. Επιλέξτε "Δίκτυο Tor" για να μάθετε πώς σας προστατεύουμε σε επίπεδο δικτύου.
onboarding.tour-tor-privacy.button=Πάμε στο Δίκτυο Tor
@@ -15,28 +15,28 @@ onboarding.tour-tor-privacy.button=Πάμε στο Δίκτυο Tor
onboarding.tour-tor-network=Δίκτυο Tor
onboarding.tour-tor-network.title=Ας ταξιδέψουμε σε ένα αποκεντρωμένο δίκτυο.
onboarding.tour-tor-network.description=Ο Tor Browser σας συνδέει στο δίκτυο Tor, που λειτουργεί χάρη σε χιλιάδες εθελοντές από όλο τον κόσμο. Σε αντίθεση με ένα VPN, δεν υπάρχει κανένα σημείο αποτυχίας ή κεντρική οντότητα που πρέπει να εμπιστευτείτε για να απολαύσετε το διαδίκτυο ιδιωτικά.
-onboarding.tour-tor-network.description-para2=ΝΕΟ: Ρυθμίσεις δικτύου Tor, συμπεριλαμβάνει την δυνατότητα αίτησης γεφύρωσης όπου είναι αποκλεισμένο το Tor, θα τα βρείτε στις Προτιμήσεις.
-onboarding.tour-tor-network.action-button=Προσαρμόστε τις ρυθμίσεις δικτύου σας Tor
+onboarding.tour-tor-network.description-para2=ΝΕΟ: Ρυθμίσεις δικτύου Tor, περιλαμβάνει τη δυνατότητα αίτησης γεφυρών όταν το Tor είναι αποκλεισμένο, θα τα βρείτε στις Προτιμήσεις.
+onboarding.tour-tor-network.action-button=Προσαρμόστε τις ρυθμίσεις του δικτύου Tor
onboarding.tour-tor-network.button=Πάμε στην προεπισκόπηση κυκλώματος
onboarding.tour-tor-circuit-display=Προεπισκόπηση κυκλώματος
onboarding.tour-tor-circuit-display.title=Δείτε το μονοπάτι σας.
onboarding.tour-tor-circuit-display.description=Για κάθε ιστοσελίδα που επισκέπτεστε η κίνησή σας συνδέεται και κρυπτογραφείται σε ένα κύκλωμα εντός τριών συνδέσεων του Tor σε όλο τον κόσμο. Μπορείτε να αιτηθείτε κανούριου κυκλώματος επιλέγοντας "Νέο κύκλωμα για αυτήν τη σελίδα" στην προεπισκόπηση κυκλώματός μας.
-onboarding.tour-tor-circuit-display.button=Βλέπω το μονοπάτι μου
-onboarding.tour-tor-circuit-display.next-button=Πηγαίνετε στην Ασφάλεια
+onboarding.tour-tor-circuit-display.button=Εμφάνιση του μονοπατιού μου
+onboarding.tour-tor-circuit-display.next-button=Πάμε στην Ασφάλεια
onboarding.tour-tor-security=Ασφάλεια
onboarding.tour-tor-security.title=Επιλέξτε την εμπειρία σας.
onboarding.tour-tor-security.description=Μπορούμε να προσφέρουμε επιπρόσθετες ρυθμίσεις για να ενισχύσουμε την ασφάλεια του περιηγητή σας. Οι Ρυθμίσεις Ασφαλείας σας επιτρέπουν να μπλοκάρεετε στοιχεία που θα μπορούσαν να χρησιμοποιηθούν για επιθέσεις στον υπολογιστή σας. Επίλεξτε παρακάτω για να δείτε τι κάνουν οι διαφορετικές ρυθμίσεις.
onboarding.tour-tor-security.description-suffix=Σημείωση: Τυπικά, το NoScript και το HTTPS Everywhere δεν συμπεριλαμβάνονται στη γραμμή εργαλείων, αλλά μπορείτε να τροποποιήσετε τη γραμμή εργαλείων σας για να τα προσθέσετε.
onboarding.tour-tor-security-level.button=Προβολή του επίπεδου ασφαλείας σας
-onboarding.tour-tor-security-level.next-button=Πηγαίνετε στις Συμβουλές Εμπειρίας
+onboarding.tour-tor-security-level.next-button=Πάμε στις Συμβουλές Εμπειρίας
-onboarding.tour-tor-expect-differences=Προτάσεις εμπειρίας
+onboarding.tour-tor-expect-differences=Συμβουλές εμπειρίας
onboarding.tour-tor-expect-differences.title=Κάποιες διαφορές είναι αναμενόμενες.
onboarding.tour-tor-expect-differences.description=Με όλη την ασφάλεια και την ιδιωτικότητα που παρέχει το Tor, η εμπειρία σας κατά την περιήγηση θα είναι λίγο διαφορετική. Κάποια πράγματα θα γίνουν λίγο πιο αργά και ανάλογα με το επίπεδο ασφάλειας, κάποια στοιχεία μπορεί να μην λειτουργούν ή να μην φορτώνονται. Επίσης, μπορεί να ερωτηθείτε αν είστε άνθρωπος και όχι ρομπότ.
onboarding.tour-tor-expect-differences.button=Δείτε τις Συχνές Ερωτήσεις
-onboarding.tour-tor-expect-differences.next-button=Πηγαίνετε στις Υπηρεσίες Onion
+onboarding.tour-tor-expect-differences.next-button=Πάμε στις Υπηρεσίες Onion
onboarding.tour-tor-onion-services=Υπηρεσίες Onion
onboarding.tour-tor-onion-services.title=Προστατευτείτε πιο πολύ.
@@ -63,10 +63,10 @@ onboarding.tor-circuit-display.two-of-three=2 από 3
onboarding.tor-circuit-display.three-of-three=3 από 3
onboarding.tor-circuit-display.intro.title=Πώς λειτουργούν τα κυκλώματα;
-onboarding.tor-circuit-display.intro.msg=Τα κυκλώματα δημιουργούνται σε τυχαία ανατιθέμενες συνδέσεις, που βρίσκονται σε υπολόγιστες σε όλο τον κόσμο ρυθμισμένοι να προωθούν την κίνηση στο Tor. Τα κυκλώματα σας επιτρέπουν να περιηγηθείτε με ιδιωτικότητα και να συνδεθείτε σε υπηρεσίες του Tor.
+onboarding.tor-circuit-display.intro.msg=Τα κυκλώματα δημιουργούνται από αναμεταδότες που ορίζονται τυχαία. Αυτοί είναι υπολογιστές σε όλο τον κόσμο ρυθμισμένοι να προωθούν την κίνηση του Tor. Τα κυκλώματα σάς επιτρέπουν να περιηγηθείτε με ιδιωτικότητα και να συνδεθείτε σε υπηρεσίες onion.
onboarding.tor-circuit-display.diagram.title=Προεπισκόπηση κυκλώματος
-onboarding.tor-circuit-display.diagram.msg=Αυτό το διάγραμμα δείχνει τις συνδέσεις που αποτελούν το κύκλωμα για αυτήν την ιστοσελίδα. Για να αποφύγετε τη σύνδεση της δραστηριότητας από σελίδα σε σελίδα, κάθε ιστοσελίδα παίρνει διαφορετικό κύκλωμα.
+onboarding.tor-circuit-display.diagram.msg=Αυτό το διάγραμμα δείχνει τους αναμεταδότες που αποτελούν το κύκλωμα για αυτήν την ιστοσελίδα. Για να αποφευχθεί η σύνδεση της δραστηριότητάς σας από σελίδα σε σελίδα, κάθε ιστοσελίδα παίρνει διαφορετικό κύκλωμα.
onboarding.tor-circuit-display.new-circuit.title=Χρειάζεστε καινούριο κύκλωμα;
onboarding.tor-circuit-display.new-circuit.msg=Αν δεν μπορείτε να συνδεθείτε στην ιστοσελίδα που προσπαθείτε να συνδεθείτε ή αν δεν φορτώνει σωστά, τότε μπορείτε να χρησιμοποιήσετε αυτό το κουμπί για να ανανεώσετε τη σελίδα με νέο κύκλωμα.
diff --git a/chrome/locale/el/torbutton.dtd b/chrome/locale/el/torbutton.dtd
index 4e8dd1c0..138ae11e 100644
--- a/chrome/locale/el/torbutton.dtd
+++ b/chrome/locale/el/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Οι προσαρμοσμένες προτιμήσεις του browser σας έχουν οδηγήσει σε ασυνήθιστες ρυθμίσεις ασφάλειας. Για λόγους ασφαλείας και ιδιωτικότητας, προτείνουμε να επιλέξετε ένα από τα προεπιλεγμένα επίπεδα ασφάλειας.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Επαναφορά προεπιλογών">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Ρυθμίσεις ασφαλείας για προχωρημένους...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Κύκλωμα Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Νέο κύκλωμα για αυτή την ιστοσελίδα">
diff --git a/chrome/locale/el/torbutton.properties b/chrome/locale/el/torbutton.properties
index 6fdfd1b2..04cce1c2 100644
--- a/chrome/locale/el/torbutton.properties
+++ b/chrome/locale/el/torbutton.properties
@@ -2,7 +2,7 @@ torbutton.circuit_display.internet = Διαδίκτυο
torbutton.circuit_display.ip_unknown = Άγνωστη διεύθυνση IP
torbutton.circuit_display.onion_site = Ιστότοπος Onion
torbutton.circuit_display.this_browser = Αυτός ο browser
-torbutton.circuit_display.relay = Αναμεταδοση
+torbutton.circuit_display.relay = Αναμεταδότης
torbutton.circuit_display.tor_bridge = Γέφυρα
torbutton.circuit_display.unknown_country = Άγνωστη χώρα
torbutton.circuit_display.guard = Φύλακας
@@ -94,12 +94,12 @@ onionServices.clientAuthMissing.longDescription=Details: %S - Ο πελάτης
onionServices.clientAuthIncorrect.pageTitle=Αποτυχία εξουσιοδότησης
onionServices.clientAuthIncorrect.header=Αποτυχία εξουσιοδότησης σελίδας onion
onionServices.clientAuthIncorrect=Το κλειδί που δόθηκε δεν είναι σωστό ή έχει ανακληθεί. Επικοινωνήστε με τον διαχειριστή της σελίδας onion.
-onionServices.clientAuthIncorrect.longDescription=Details: %S - Ο πελάτης μπόρεσε να πραγματοποιήσει λήψη του ζητούμενου περιγραφέα υπηρεσίας onion , αλλά δεν μπόρεσε να αποκρυπτογραφήσει το περιεχόμενό του χρησιμοποιώντας τις παρεχόμενες πληροφορίες εξουσιοδότησης πελάτη. Αυτό μπορεί να σημαίνει ότι η πρόσβαση έχει ανακληθεί.
+onionServices.clientAuthIncorrect.longDescription=Λεπτομέρειες: %S — Ο πελάτης μπόρεσε να κατεβάσει τον ζητούμενο περιγραφέα υπηρεσίας onion , αλλά δεν μπόρεσε να αποκρυπτογραφήσει το περιεχόμενό του χρησιμοποιώντας τις παρεχόμενες πληροφορίες εξουσιοδότησης πελάτη. Αυτό μπορεί να σημαίνει ότι η πρόσβαση έχει ανακληθεί.
# Tor SOCKS error 0xF6:
onionServices.badAddress.pageTitle=Σφάλμα φόρτωσης σελίδας Onion
onionServices.badAddress.header=Άκυρη διεύθυνση σελίδας onion
onionServices.badAddress=Η διεύθυνση της σελίδας onion που καταχωρήθηκε δεν είναι έγκυρη. Παρακαλώ ελέγξτε ότι την έχετε εισάγει σωστά.
-onionServices.badAddress.longDescription=Details: %S - Η παρεχόμενη διεύθυνση .onion δεν είναι έγκυρη. Αυτό το σφάλμα επιστρέφεται για έναν από τους ακόλουθους λόγους: η διεύθυνση ελέγχου δεν ταιριάζει, το δημόσιο κλειδί ed25519 δεν είναι έγκυρο ή η κωδικοποίηση δεν είναι έγκυρη.
+onionServices.badAddress.longDescription=Λεπτομέρειες: %S — Η παρεχόμενη διεύθυνση .onion δεν είναι έγκυρη. Αυτό το σφάλμα εμφανίζεται για έναν από τους ακόλουθους λόγους: η διεύθυνση ελέγχου δεν ταιριάζει, το δημόσιο κλειδί ed25519 δεν είναι έγκυρο ή η κωδικοποίηση δεν είναι έγκυρη.
# Tor SOCKS error 0xF7:
onionServices.introTimedOut.pageTitle=Σφάλμα φόρτωσης σελίδας Onion
onionServices.introTimedOut.header=Εληξε ο χρόνος Onionsite Circuit Creation
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=Απομάκρυνση
onionServices.authPreferences.removeAll=Αφαίρεση όλων
onionServices.authPreferences.failedToGetKeys=Αδυναμία λήψης κλειδιών από το tor
onionServices.authPreferences.failedToRemoveKey=Αδυναμία αφαίρεσης κλειδιού
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
+onionServices.v2Deprecated.pageTitle=Προειδοποίηση κατάργησης ιστοσελίδας Onion V2
+onionServices.v2Deprecated.header=Οι ιστοσελίδες Onion έκδοσης 2 θα καταργηθούν σύντομα
+onionServices.v2Deprecated=Αυτή η σελίδα onion δεν θα είναι προσβάσιμη σύντομα. Παρακαλούμε επικοινωνήστε με τον διαχειριστή της σελίδας και προτρέψτε τον να την αναβαθμίσει.
+onionServices.v2Deprecated.longDescription=Το Tor σταματά την υποστήριξη υπηρεσιών onion έκδοσης 2, ξεκινώντας από τον Ιούλιο 2021 οπότε και αυτή η σελίδα δεν θα είναι διαθέσιμη από αυτή τη διεύθυνση.
onionServices.v2Deprecated.tryAgain=Το κατάλαβα
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.tooltip=Αυτή η σελίδα onion δεν θα είναι σύντομα προσβάσιμη
# Onion-Location strings.
onionLocation.alwaysPrioritize=Πάντα να δίνεται προτεραιότητα στα Onion
@@ -146,11 +146,11 @@ onionLocation.prioritizeOnionsDescription=Να δίνεται προτεραιό
onionLocation.onionServicesTitle=Υπηρεσίες Onion
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
-cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
-cryptoSafetyPrompt.whatCanHeading=What can you do about it?
-cryptoSafetyPrompt.whatCanBody=You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning.
+cryptoSafetyPrompt.cryptoWarning=Η διεύθυνση κρυπτονομίσματος (%S) αντιγράφηκε από μη ασφαλή ιστοσελίδα. Μπορεί να έχει τροποποιηθεί.
+cryptoSafetyPrompt.whatCanHeading=Τι μπορείτε να κάνετε γι αυτό;
+cryptoSafetyPrompt.whatCanBody=Μπορείτε να δοκιμάσετε να επανασυνδεθείτε με νέο κύκλωμα για να δημιουργήσετε μια ασφαλή σύνδεση, ή να αποδεχτείτε το ρίσκο και να αγνοήσετε αυτήν την προειδοποίηση.
cryptoSafetyPrompt.learnMore=Μάθετε περισσότερα
-cryptoSafetyPrompt.primaryAction=Reload Tab with a New Circuit
+cryptoSafetyPrompt.primaryAction=Ανανέωση καρτέλας με νέο κύκλωμα
cryptoSafetyPrompt.primaryActionAccessKey=R
-cryptoSafetyPrompt.secondaryAction=Dismiss Warning
+cryptoSafetyPrompt.secondaryAction=Αγνόηση προειδοποίησης
cryptoSafetyPrompt.secondaryActionAccessKey=B
diff --git a/chrome/locale/es-AR/aboutTor.dtd b/chrome/locale/es-AR/aboutTor.dtd
index df88805e..70d667bd 100644
--- a/chrome/locale/es-AR/aboutTor.dtd
+++ b/chrome/locale/es-AR/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "NO\nTOQUÉS\nMIS\nDATOS">
<!ENTITY aboutTor.yec.motto "La privacidad es un derecho humano">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/es-AR/torbutton.dtd b/chrome/locale/es-AR/torbutton.dtd
index 795a71f1..f478bcb5 100644
--- a/chrome/locale/es-AR/torbutton.dtd
+++ b/chrome/locale/es-AR/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Tus preferencias personalizadas del navegador han resultado en ajustes de seguridad inusuales. Por razones de seguridad y privacidad, recomendamos que elijas uno de los niveles de seguridad por defecto.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Restablecer valores por defecto">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Configuración de Seguridad Avanzada">
+<!ENTITY torbutton.prefs.sec_change "Cambiar...">
<!ENTITY torbutton.circuit_display.title "Circuito Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Nuevo circuito para este sitio">
diff --git a/chrome/locale/es-ES/torbutton.dtd b/chrome/locale/es-ES/torbutton.dtd
index 9766a7da..cc269790 100644
--- a/chrome/locale/es-ES/torbutton.dtd
+++ b/chrome/locale/es-ES/torbutton.dtd
@@ -7,7 +7,7 @@
<!ENTITY torbutton.context_menu.downloadUpdate "Comprobar actualización del Tor Browser...">
<!ENTITY torbutton.context_menu.downloadUpdate.key "a">
<!ENTITY torbutton.context_menu.cookieProtections "Protecciones de cookie...">
-<!ENTITY torbutton.context_menu.cookieProtections.key "C">
+<!ENTITY torbutton.context_menu.cookieProtections.key "g">
<!ENTITY torbutton.button.tooltip "Haga clic para inicializar Torbutton">
<!ENTITY torbutton.prefs.security_settings "Configuración de seguridad del Tor Browser">
<!ENTITY torbutton.cookiedialog.title "Administrar protecciones de cookie">
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Tus preferencias personalizadas para el navegador han resultado en una configuración de seguridad inusual. Por motivos de seguridad y privacidad, te recomendamos uno de los de los niveles de seguridad predeterminados.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Restaurar valores predeterminados">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Configuración de seguridad avanzada ...">
+<!ENTITY torbutton.prefs.sec_change "Cambiar...">
<!ENTITY torbutton.circuit_display.title "Circuito Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Nuevo Circuito para este Sitio">
diff --git a/chrome/locale/es-ES/torbutton.properties b/chrome/locale/es-ES/torbutton.properties
index 99a5fcc9..854361a7 100644
--- a/chrome/locale/es-ES/torbutton.properties
+++ b/chrome/locale/es-ES/torbutton.properties
@@ -12,13 +12,13 @@ torbutton.circuit_display.click_to_copy = Click para copiar
torbutton.circuit_display.copied = ¡Copiado!
torbutton.content_sizer.margin_tooltip = El Tor Browser añade este margen para hacer el ancho y el alto de tu ventana menos especial, y reducir de esta forma la posibilidad de rastrearte en línea.
extensions.torbutton(a)torproject.org.description = Torbutton proporciona un botón para configurar las preferencias de Tor y limpiar rápida y fácilmente los datos de navegación privada.
-torbutton.popup.external.title = ¿Descargar un tipo de fichero externo?
-torbutton.popup.external.app = El Tor Browser no puede mostrar este fichero. Tendrás que abrirlo con otra aplicación.\n\n
-torbutton.popup.external.note = Algunos tipos de ficheros pueden hacer que ciertas aplicaciones se conecten a Internet sin usar Tor.\n\n
+torbutton.popup.external.title = ¿Descargar un tipo de archivo externo?
+torbutton.popup.external.app = El Tor Browser no puede mostrar este archivo. Tendrás que abrirlo con otra aplicación.\n\n
+torbutton.popup.external.note = Algunos tipos de archivos pueden hacer que ciertas aplicaciones se conecten a Internet sin usar Tor.\n\n
torbutton.popup.external.suggest = Para estar seguro, deberías abrir únicamente los archivos descargados cuando no esté conectado, o usar un Live CD (autoarrancable) de Tor como Tails.\n
-torbutton.popup.launch = Descargar fichero
+torbutton.popup.launch = Descargar archivo
torbutton.popup.cancel = Cancelar
-torbutton.popup.dontask = Descargar ficheros automáticamente a partir de ahora
+torbutton.popup.dontask = Descargar archivos automáticamente a partir de ahora
torbutton.popup.no_newnym = Torbutton no puede darte una nueva identidad (instancia de Tor) de forma segura. No tiene acceso al puerto de control de Tor (ControlPort)\n\n¿Estás ejecutando el Tor Browser Bundle?
torbutton.security_settings.menu.title = Configuración de seguridad
torbutton.title.prompt_torbrowser = Información importante sobre Torbutton
@@ -27,7 +27,7 @@ torbutton.popup.short_torbrowser = ¡Información importante sobre Torbutton! \n
torbutton.popup.confirm_plugins = Complementos (plugins) como Flash pueden dañar tu privacidad y anonimato.\n\nTambién pueden esquivar Tor revelando tu ubicación y dirección IP actuales.\n\n¿Estás seguro de que quieres habilitar los complementos?\n\n
torbutton.popup.never_ask_again = No me vuelvas a preguntar
-torbutton.popup.confirm_newnym = El Tor Browser cerrará todas las ventanas y pestañas. Todas las sesiones de sitios web se perderán.\n\n¿Reiniciar el Tor Browser para restablecer su identidad?\n\n
+torbutton.popup.confirm_newnym = El Navegador Tor cerrará todas las ventanas y pestañas. Todas las sesiones de sitios web se perderán.\n\n¿Reiniciar el Navegador Tor para restablecer tu identidad?\n\n
torbutton.maximize_warning = Maximizar el Tor Browser puede permitir a los sitios web determinar el tamaño de tu monitor, lo que podría usarse para rastrearte. Te recomendamos que dejes las ventanas del Tor Browser en su tamaño predeterminado.
@@ -43,9 +43,9 @@ canvas.neverAccessKey=u
# Profile/startup error messages. Strings are kept here for ease of translation.
# LOCALIZATION NOTE: %S is the application name.
profileProblemTitle=Problema del perfil %S
-profileReadOnly=No puede ejecutar %S desde un sistema de ficheros de solo-lectura. Copie %S a otra ubicación antes de intentar usarlo.
-profileReadOnlyMac=No puede ejecutar %S desde un sistema de ficheros de solo-lectura. Copie %S a su escritorio o la carpeta de aplicaciones antes de intentar usarlo.
-profileAccessDenied=%S no tiene permiso para acceder al perfil. Ajuste los permisos de su sistema de ficheros e inténtelo de nuevo.
+profileReadOnly=No puede ejecutar %S desde un sistema de archivos de solo-lectura. Copie %S a otra ubicación antes de intentar usarlo.
+profileReadOnlyMac=No puede ejecutar %S desde un sistema de archivos de solo-lectura. Copie %S a su escritorio o la carpeta de aplicaciones antes de intentar usarlo.
+profileAccessDenied=%S no tiene permiso para acceder al perfil. Ajuste los permisos de su sistema de archivos e inténtelo de nuevo.
profileMigrationFailed=Ha ocurrido un error en la migración de tu perfil %S. \nSe usarán los nuevos ajustes.
# "Downloading update" string for the hamburger menu (see #28885).
@@ -62,52 +62,52 @@ pageInfo_OnionName=Nombre de la cebolla:
onionServices.learnMore=Conocer más
onionServices.errorPage.browser=Navegador
onionServices.errorPage.network=Red
-onionServices.errorPage.onionSite=Onionsite
+onionServices.errorPage.onionSite=Sitio cebolla
# LOCALIZATION NOTE: In the longDescription strings, %S will be replaced with
# an error code, e.g., 0xF3.
# Tor SOCKS error 0xF0:
-onionServices.descNotFound.pageTitle=Problemas cargando Onionsite
-onionServices.descNotFound.header=No se encuentra Onionsite
+onionServices.descNotFound.pageTitle=Problemas cargando el sitio cebolla
+onionServices.descNotFound.header=No se encuentra el sitio cebolla
onionServices.descNotFound=La causa más probable es que el sitio cebolla esté fuera de línea. Contacta con su administrador.
onionServices.descNotFound.longDescription=Detalles: %S - El descriptor del servicio de onion solicitado no se encuentra en el hashring y por lo tanto el servicio no está accesible para el cliente.
# Tor SOCKS error 0xF1:
-onionServices.descInvalid.pageTitle=Problemas al cargar Sitio Onion
-onionServices.descInvalid.header=No se puede llegar a Onionsite
-onionServices.descInvalid=No se puede llegar al sitio cebolla a causa de un error interno.
-onionServices.descInvalid.longDescription=Detalles: %S - El descriptor de servicio de onion solicitado no se puede analizar o la validación de la firma falló.
+onionServices.descInvalid.pageTitle=Problemas al cargar el sitio cebolla
+onionServices.descInvalid.header=No se puede acceder al sitio cebolla
+onionServices.descInvalid=El sitio cebolla está inaccesible debido a un error interno.
+onionServices.descInvalid.longDescription=Detalles: %S — El descriptor de servicio cebolla solicitado no se puede analizar o la validación de la firma falló.
# Tor SOCKS error 0xF2:
-onionServices.introFailed.pageTitle=Problemas cargando Onionsite
-onionServices.introFailed.header=Se ha desconectado el sitio onion
-onionServices.introFailed=La causa más probable es que onionsite esté fuera de línea. Contacta con el administrador de onionsite
+onionServices.introFailed.pageTitle=Problemas cargando el sitio cebolla
+onionServices.introFailed.header=Se ha desconectado el sitio cebolla
+onionServices.introFailed=La causa más probable es que el sitio cebolla esté fuera de línea. Contacta con su administrador.
onionServices.introFailed.longDescription=Detalles: %S - La introducción falló, lo que significa que el descriptor fue encontrado pero el servicio ya no está conectado al punto de introducción. Es probable que el servicio haya cambiado su descriptor o que no esté funcionando.
# Tor SOCKS error 0xF3:
-onionServices.rendezvousFailed.pageTitle=Problemas cargando Onionsite
-onionServices.rendezvousFailed.header=Incapaz de conectar a Onionsite
+onionServices.rendezvousFailed.pageTitle=Problema cargando el sitio cebolla
+onionServices.rendezvousFailed.header=No se pudo conectar al sitio cebolla
onionServices.rendezvousFailed=El sitio cebolla está ocupado o la red Tor está sobrecargada. Inténtalo más tarde.
onionServices.rendezvousFailed.longDescription=Detalles: %S - El cliente no encontró el servicio, lo que significa que el cliente no pudo finalizar la conexión.
# Tor SOCKS error 0xF4:
onionServices.clientAuthMissing.pageTitle=Se requiere autorización
-onionServices.clientAuthMissing.header=Onionsite requiere autorización
+onionServices.clientAuthMissing.header=El sitio cebolla requiere autorización
onionServices.clientAuthMissing=El acceso al sitio cebolla necesita una clave, pero no se ha proporcionado ninguna.
onionServices.clientAuthMissing.longDescription=Detalles: %S - El cliente descargó el descriptor de servicio de cebolla solicitado, pero no pudo descifrar su contenido porque falta la información de autorización del cliente.
# Tor SOCKS error 0xF5:
onionServices.clientAuthIncorrect.pageTitle=Falló la autorización
-onionServices.clientAuthIncorrect.header=Falló la autenticación del Onionsite
-onionServices.clientAuthIncorrect=La clave proporcionada es incorrecta o ha sido revocada. Contacta con el administrador del sitio web.
+onionServices.clientAuthIncorrect.header=Falló la autenticación del sitio cebolla
+onionServices.clientAuthIncorrect=La clave proporcionada es incorrecta o ha sido revocada. Contacta con el administrador del sitio cebolla.
onionServices.clientAuthIncorrect.longDescription=Detalles: %S - El cliente pudo descargar el descriptor de servicio de cebolla solicitado pero no pudo descifrar su contenido usando la información de autorización del cliente proporcionada. Esto puede significar que el acceso ha sido revocado.
# Tor SOCKS error 0xF6:
onionServices.badAddress.pageTitle=Problemas al cargar sitio cebolla
-onionServices.badAddress.header=Invalidada dirección de Onionsite
+onionServices.badAddress.header=Dirección de sitio cebolla inválida
onionServices.badAddress=La dirección del sitio cebolla no es válida. Por favor, comprueba que la has introducido correctamente.
-onionServices.badAddress.longDescription=Detalles: %S — La dirección de la cebolla es inválida. Este error se da debido a una de las siguientes razones: la suma de comprobación de la dirección no coincide, la clave pública ed25519 es inválida, o la codificación es inválida.
+onionServices.badAddress.longDescription=Detalles: %S — La dirección .onion proporcionada es inválida. Este error se da debido a una de las siguientes razones: la suma de comprobación de la dirección no coincide, la clave pública ed25519 es inválida, o la codificación es inválida.
# Tor SOCKS error 0xF7:
-onionServices.introTimedOut.pageTitle=Problemas cargando Onionsite
-onionServices.introTimedOut.header=La creación del circuito de Onionsite se ha agotado
-onionServices.introTimedOut=No te has conectado a onionsite, quizá por una mala conexión de red.
-onionServices.introTimedOut.longDescription=Detalles: %S - Se ha agotado la conexión solicitada con el servicio de onion, mientras se intentaba construir el circuito de encuentro.
+onionServices.introTimedOut.pageTitle=Problema cargando el sitio cebolla
+onionServices.introTimedOut.header=La creación del circuito al sitio cebolla ha agotado el tiempo preestablecido
+onionServices.introTimedOut=Ha fallado la conexión al sitio cebolla, posiblemente debido a una mala conexión de red.
+onionServices.introTimedOut.longDescription=Detalles: %S — Se ha agotado la conexión solicitada con el servicio cebolla, mientras se intentaba construir el circuito de encuentro.
#
# LOCALIZATION NOTE: %S will be replaced with the .onion address.
-onionServices.authPrompt.description2=%S está pidiendo que se autentique.
+onionServices.authPrompt.description2=%S está pidiendo que te acredites.
onionServices.authPrompt.keyPlaceholder=Introduce tu clave privada para este servicio cebolla
onionServices.authPrompt.done=Listo
onionServices.authPrompt.doneAccessKey=r
@@ -124,20 +124,20 @@ onionServices.authPreferences.remove=Eliminar
onionServices.authPreferences.removeAll=Eliminar todo
onionServices.authPreferences.failedToGetKeys=No se pueden descargar las claves de Tor
onionServices.authPreferences.failedToRemoveKey=No se puede quitar la clave
-onionServices.v2Deprecated.pageTitle=Advertencia de depreciación del sitio V2 Onion
-onionServices.v2Deprecated.header=Pronto se depreciará el sitio Version 2 Onion
-onionServices.v2Deprecated=Pronto no será accesible este sitio onion. Por favor, contacta con el administrador del sitio y animale a actualizar
-onionServices.v2Deprecated.longDescription=Tor terminará su apoyo a los servicios onion de la versión 2 a partir de julio de 2021, y este sitio onion ya no será accesible en esta dirección. Si eres el administrador del sitio, actualizar a una versión 3 el servicio onion pronto.
+onionServices.v2Deprecated.pageTitle=Advertencia de obsolescencia del sitio cebolla V2
+onionServices.v2Deprecated.header=Pronto los sitios cebolla Versión 2 quedarán obsoletos
+onionServices.v2Deprecated=Pronto no será accesible este sitio cebolla. Por favor, contacta con el administrador del sitio y anímale a actualizar.
+onionServices.v2Deprecated.longDescription=Tor terminará su apoyo a los servicios cebolla versión 2 a partir de julio de 2021, y este sitio cebolla ya no será accesible en esta dirección. Si eres el administrador del sitio, actualízalo lo antes posible a la versión 3.
onionServices.v2Deprecated.tryAgain=Entendido
onionServices.v2Deprecated.tooltip=Este sitio onion pronto no será accesible
# Onion-Location strings.
-onionLocation.alwaysPrioritize=Priorizar siempre Onions.
+onionLocation.alwaysPrioritize=Priorizar siempre sitios cebolla
onionLocation.alwaysPrioritizeAccessKey=a
onionLocation.notNow=Ahora no
onionLocation.notNowAccessKey=b
-onionLocation.description=Hay una versión más privada y segura de este sitio disponible en la red Tor a través de los servicios de cebolla. Los servicios de cebolla ayudan a los editores de sitios web y a sus visitantes a derrotar la vigilancia y la censura.
-onionLocation.tryThis=Intenta los servicios de cebolla
+onionLocation.description=Hay una versión más privada y segura de este sitio disponible en la red Tor a través de los servicios cebolla. Los servicios cebolla ayudan a los editores de sitios web y a sus visitantes a derrotar la vigilancia y la censura.
+onionLocation.tryThis=Prueba los servicios cebolla
onionLocation.onionAvailable=.onion disponible
onionLocation.learnMore=Saber más
onionLocation.always=Siempre
@@ -152,5 +152,5 @@ cryptoSafetyPrompt.whatCanBody=Puedes conectar con un nuevo circuito para establ
cryptoSafetyPrompt.learnMore=Aprende más
cryptoSafetyPrompt.primaryAction=Recargar Tab con un nuevo circuito
cryptoSafetyPrompt.primaryActionAccessKey=R
-cryptoSafetyPrompt.secondaryAction=Desestimar la advertencia
+cryptoSafetyPrompt.secondaryAction=Ignorar advertencia
cryptoSafetyPrompt.secondaryActionAccessKey=B
diff --git a/chrome/locale/eu/torbutton.dtd b/chrome/locale/eu/torbutton.dtd
index 1af7c119..dbb358a8 100644
--- a/chrome/locale/eu/torbutton.dtd
+++ b/chrome/locale/eu/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Zure nabigatzailearen hobespenek segurtasun ezarpen ezohikoak izatea eragin dute. Segurtasun eta pribatutasun arrazoiak direla medio, gomendatzen dizugu segurtasun maila lehenetsitako bat aukeratzea.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Lehenetsiak berrezarri">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Segurtasun ezarpen aurreratuak…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor Zirkuitoa">
<!ENTITY torbutton.circuit_display.new_circuit "Zirkuito berria Gune honetarako">
diff --git a/chrome/locale/fa/torbutton.dtd b/chrome/locale/fa/torbutton.dtd
index c650f3df..e56db4fa 100644
--- a/chrome/locale/fa/torbutton.dtd
+++ b/chrome/locale/fa/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "تنظیمات سفارشی شما در مرورگر منجر به تغییرات غیر معمول در تنظیمات امنیتی شده است.برای امن نگه داشتن حریم خصوصی خود ما پیشنهاد میکنیم یکی از تنظیمات پیشفرض امنیتی را انتخاب کنید. ">
<!ENTITY torbutton.prefs.sec_restore_defaults "بازگردانی تنظیمات اولیه">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "تنظیمات پیشرفته امنیت ...">
+<!ENTITY torbutton.prefs.sec_change "تغییر...">
<!ENTITY torbutton.circuit_display.title "مدار Tor">
<!ENTITY torbutton.circuit_display.new_circuit "مدار جدید برای این سایت">
diff --git a/chrome/locale/fa/torbutton.properties b/chrome/locale/fa/torbutton.properties
index fa33a2f5..00571fc0 100644
--- a/chrome/locale/fa/torbutton.properties
+++ b/chrome/locale/fa/torbutton.properties
@@ -1,6 +1,6 @@
torbutton.circuit_display.internet = اینترنت
-torbutton.circuit_display.ip_unknown = IP ناشناخته
-torbutton.circuit_display.onion_site = سایت پیاز
+torbutton.circuit_display.ip_unknown = آیپی ناشناخته
+torbutton.circuit_display.onion_site = سایت پیازی
torbutton.circuit_display.this_browser = این مرورگر
torbutton.circuit_display.relay = بازپخش
torbutton.circuit_display.tor_bridge = پل
@@ -9,7 +9,7 @@ torbutton.circuit_display.guard = محافظ
torbutton.circuit_display.guard_note = گره [گارد] شما ممکن است تغییر نکند.
torbutton.circuit_display.learn_more = اطلاعات بیشتر
torbutton.circuit_display.click_to_copy = برای کپی کلیک کنید
-torbutton.circuit_display.copied = کپیشد!
+torbutton.circuit_display.copied = کپی شد!
torbutton.content_sizer.margin_tooltip = مرورگر Tor اضافه می کند این حاشیه را به عرض و ارتفاع پنجره شما که کمتر مشخص شود، و در نتیجه باعث کاهش توانایی به ردیابی آنلاین شما شود.
extensions.torbutton(a)torproject.org.description = Torbutton دکمه ای را برای شما فراهم مینماید تا تنظیمات "تر" را پیکربندی کرده و بتوانید به راحتی و سرعت، داده های خصوصی مرورگرتان را پاک کنید.
torbutton.popup.external.title = میخواهید یک فایل نوع بیرونی دانلود شود؟
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=حذف
onionServices.authPreferences.removeAll=حذف کردن همه
onionServices.authPreferences.failedToGetKeys=قادر به بازیابی کلیدها از تور نیستیم
onionServices.authPreferences.failedToRemoveKey=قادر به حذف کردن کلید نیستیم
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
+onionServices.v2Deprecated.pageTitle=هشدار از کار افتادن سایت پیازی نسخه ۲
+onionServices.v2Deprecated.header=سایتهای پیازی نسخه ۲ به زودی از کار خواهند افتاد
+onionServices.v2Deprecated=سایت پیازی به زودی قابل دسترس نخواهد بود. لطفاً با مدیر سایت ارتباط برقرار کرده و آن ها را تشویق به ارتقا نمایید.
+onionServices.v2Deprecated.longDescription=از اول ژولای ۲۰۲۱ تور در حال پایان دادن به پشتیبانی از نسخه ۲ سرویسهای پیازی است، و این سایت پیازی دیگر از این نشانی قابل دسترس نمی باشد. اگر مدیر سایت هستید، آن را به سرویس پیازی نسخه ۳ ارتقا دهید.
onionServices.v2Deprecated.tryAgain=متوجه شدم
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.tooltip=سایت پیازی به این زودی قابل دسترس نخواهد بود
# Onion-Location strings.
onionLocation.alwaysPrioritize=همیشه پیازها را در اولویت قرار بده
@@ -146,11 +146,11 @@ onionLocation.prioritizeOnionsDescription=سایتهای .onion را در
onionLocation.onionServicesTitle=خدمات پیازی
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
-cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
-cryptoSafetyPrompt.whatCanHeading=What can you do about it?
-cryptoSafetyPrompt.whatCanBody=You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning.
+cryptoSafetyPrompt.cryptoWarning=یک نشانی رمزارز (%S) از یک سایت غیرامن کپی شده است. ممکن است تغییر یافته باشد.
+cryptoSafetyPrompt.whatCanHeading=چه کاری میتوانید انجام دهید؟
+cryptoSafetyPrompt.whatCanBody=شما میتوانید به یک زنجیره جدید وصل شوید تا یک اتصال امن برقرار کنید، یا این هشدار را رد کرده و خطرات آن را بپذیرید.
cryptoSafetyPrompt.learnMore=اطلاعات بیشتر
-cryptoSafetyPrompt.primaryAction=Reload Tab with a New Circuit
+cryptoSafetyPrompt.primaryAction=بارگذاری مجدد زبانه با یک زنجیره جدید
cryptoSafetyPrompt.primaryActionAccessKey=R
-cryptoSafetyPrompt.secondaryAction=Dismiss Warning
+cryptoSafetyPrompt.secondaryAction=رد هشدار
cryptoSafetyPrompt.secondaryActionAccessKey=B
diff --git a/chrome/locale/fr/aboutTor.dtd b/chrome/locale/fr/aboutTor.dtd
index cfda472c..4b0fbbd8 100644
--- a/chrome/locale/fr/aboutTor.dtd
+++ b/chrome/locale/fr/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "NE TOUCHEZ\nPAS\nÀ MES\nDONNÉES">
<!ENTITY aboutTor.yec.motto "La vie privée est un droit de la personne">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/fr/torbutton.dtd b/chrome/locale/fr/torbutton.dtd
index 6c60ae10..1c3c6b66 100644
--- a/chrome/locale/fr/torbutton.dtd
+++ b/chrome/locale/fr/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Les préférences personnalisées de votre navigateur ont entraîné des paramètres de sécurité inhabituels. Pour des raisons de sécurité et de protection des données personnelles, nous vous recommandons de choisir un des niveaux de sécurité par défaut.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Rétablir les paramètres par défaut">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Paramètres de sécurité avancés…">
+<!ENTITY torbutton.prefs.sec_change "Changer…">
<!ENTITY torbutton.circuit_display.title "Circuit Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Nouveau circuit pour ce site">
diff --git a/chrome/locale/ga-IE/torbutton.dtd b/chrome/locale/ga-IE/torbutton.dtd
index 8cb1458b..1576f3a6 100644
--- a/chrome/locale/ga-IE/torbutton.dtd
+++ b/chrome/locale/ga-IE/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Tá socruithe slándála an bhrabhsálaí as an ngnáth faoi láthair, mar thoradh ar do chuid sainroghanna. Ar chúiseanna slándála agus príobháideachais, molaimid duit ceann de na leibhéil slándála réamhshocraithe a roghnú.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Fill ar na Réamhshocruithe">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Ardsocruithe Slándála...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Ciorcad Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Ciorcad Nua don Suíomh seo">
diff --git a/chrome/locale/he/torbutton.dtd b/chrome/locale/he/torbutton.dtd
index bb5d21bb..576f3f17 100644
--- a/chrome/locale/he/torbutton.dtd
+++ b/chrome/locale/he/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "העדפות הדפדפן המותאמות שלך נבעו מהגדרות אבטחה בלתי שגרתיות. מטעמי אבטחה ופרטיות, אנו ממליצים לך לבחור באחת מרמות האבטחה של ברירת המחדל.">
<!ENTITY torbutton.prefs.sec_restore_defaults "שחזר ברירות מחדל">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "הגדרות אבטחה מתקדמות…">
+<!ENTITY torbutton.prefs.sec_change "שנה…">
<!ENTITY torbutton.circuit_display.title "מעגל Tor">
<!ENTITY torbutton.circuit_display.new_circuit "מעגל חדש עבור אתר זה">
diff --git a/chrome/locale/hu/torbutton.dtd b/chrome/locale/hu/torbutton.dtd
index 69aa373d..16a5522d 100644
--- a/chrome/locale/hu/torbutton.dtd
+++ b/chrome/locale/hu/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Az Ön által eszközölt egyéni böngészői beállítások eredményeképp biztonsági kockázatok merülhetnek fel. Biztonsági és adatvédelmi szempontokból kérjük válasszon az alapértelmezett biztonsági szintek közül.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Alapértelmezések visszaállítása">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Speciális biztonsági beállítások...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor áramkör">
<!ENTITY torbutton.circuit_display.new_circuit "Új Tor áramkör ehhez az oldalhoz">
diff --git a/chrome/locale/hu/torbutton.properties b/chrome/locale/hu/torbutton.properties
index 72631994..d09538fe 100644
--- a/chrome/locale/hu/torbutton.properties
+++ b/chrome/locale/hu/torbutton.properties
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=Eltávolít
onionServices.authPreferences.removeAll=Mindent eltávolít
onionServices.authPreferences.failedToGetKeys=Sikertelen a kulcsok lekérése a tor-ról
onionServices.authPreferences.failedToRemoveKey=Nem lehetséges a kulcs eltávolítása
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
+onionServices.v2Deprecated.pageTitle=V2 Onion oldal támogatás megszűnési figyelmeztetés
+onionServices.v2Deprecated.header=A Verzió 2 Onion oldalak támogatása hamarosan megszűnik
+onionServices.v2Deprecated=Ez az onion oldal hamarosan nem lesz elérhető. Kérjük vegye fel a kapcsolatot az oldal adminisztrátorával és vegye rá őket a frissítésre.
+onionServices.v2Deprecated.longDescription=A Tor megszünteti a verzió 2 onion szolgáltatásokat 2021 júliustól és ez az onion oldal a továbbiakban nem lesz elérhető ezen a címen. Ha Ön az oldal adminisztrátora, frissítsen verzió 3 onion szolgáltatásra hamarosan.
onionServices.v2Deprecated.tryAgain=Megvan
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.tooltip=Ez az onion oldal hamarosan nem lesz elérhető
# Onion-Location strings.
onionLocation.alwaysPrioritize=Mindig priorizálja az Onionokat
@@ -146,11 +146,11 @@ onionLocation.prioritizeOnionsDescription=Priorizálja a .oinion oldalt, ha isme
onionLocation.onionServicesTitle=Onion Szolgáltatások
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
-cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
-cryptoSafetyPrompt.whatCanHeading=What can you do about it?
-cryptoSafetyPrompt.whatCanBody=You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning.
+cryptoSafetyPrompt.cryptoWarning=A kriptopénz cím (%S) nem biztonságos weboldalról került másolásra. Előfordulhat, hogy módosításra került.
+cryptoSafetyPrompt.whatCanHeading=Mit tehet ez ellen?
+cryptoSafetyPrompt.whatCanBody=Megpróbálhat újra csatlakozni egy új áramkörön biztonságos kapcsolat létrehozásához vagy elfogadhatja a kockázatot és figyelmen kívül hagyhatja a figyelmeztetést.
cryptoSafetyPrompt.learnMore=További információ
-cryptoSafetyPrompt.primaryAction=Reload Tab with a New Circuit
+cryptoSafetyPrompt.primaryAction=A Fül újra töltése másik áramkörön keresztül
cryptoSafetyPrompt.primaryActionAccessKey=R
-cryptoSafetyPrompt.secondaryAction=Dismiss Warning
+cryptoSafetyPrompt.secondaryAction=Figyelmeztetés kihagyása
cryptoSafetyPrompt.secondaryActionAccessKey=B
diff --git a/chrome/locale/id/aboutTor.dtd b/chrome/locale/id/aboutTor.dtd
index 18d9755a..4918ea97 100644
--- a/chrome/locale/id/aboutTor.dtd
+++ b/chrome/locale/id/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "Jauhi\nData\nSaya">
<!ENTITY aboutTor.yec.motto "Privasi adalah hak asasi manusia">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/id/torbutton.dtd b/chrome/locale/id/torbutton.dtd
index 43197821..889af4af 100644
--- a/chrome/locale/id/torbutton.dtd
+++ b/chrome/locale/id/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Preferensi peramban khusus Anda telah membuat pengaturan keamanan yang tidak biasa. Untuk alasan keamanan dan privasi, kami menyarankan Anda untuk memilih satu dari tingkat keamanan bawaan.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Kembalikan ke Standar">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Pengaturan Keamanan Lanjutan...">
+<!ENTITY torbutton.prefs.sec_change "Ubah...">
<!ENTITY torbutton.circuit_display.title "Sirkuit Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Sirkuit Baru untuk Situs Ini">
diff --git a/chrome/locale/id/torbutton.properties b/chrome/locale/id/torbutton.properties
index 2ff58a32..0ea1611f 100644
--- a/chrome/locale/id/torbutton.properties
+++ b/chrome/locale/id/torbutton.properties
@@ -1,39 +1,39 @@
torbutton.circuit_display.internet = Internet
torbutton.circuit_display.ip_unknown = IP tidak diketahui
torbutton.circuit_display.onion_site = Situs onion
-torbutton.circuit_display.this_browser = Peramban ini
+torbutton.circuit_display.this_browser = Browser ini
torbutton.circuit_display.relay = Relay
-torbutton.circuit_display.tor_bridge = Jembatan
+torbutton.circuit_display.tor_bridge = Bridge
torbutton.circuit_display.unknown_country = Negara tidak diketahui
-torbutton.circuit_display.guard = Penjaga
-torbutton.circuit_display.guard_note = Titik [Penjaga] Anda tidak dapat berubah
+torbutton.circuit_display.guard = Guard
+torbutton.circuit_display.guard_note = Titik [Guard] Anda tidak dapat berubah
torbutton.circuit_display.learn_more = Pelajari lebih lanjut
torbutton.circuit_display.click_to_copy = Klik untuk Menyalin
torbutton.circuit_display.copied = Disalin!
-torbutton.content_sizer.margin_tooltip = Adds Browser Tor margin ini untuk membuat Lebar dan tinggi dari window anda kurang khas
-extensions.torbutton(a)torproject.org.description = Torbutton provides a button to configure Tor settings and quickly and easily clear private browsing data.
+torbutton.content_sizer.margin_tooltip = Tor Browser menambahkan margin ini untuk membuat lebar dan tinggi window Anda agar tidak terlalu mencolok, dan dengan demikian mengurangi kemampuan orang untuk melacak Anda secara online.
+extensions.torbutton(a)torproject.org.description = Torbutton menyediakan tombol untuk mengonfigurasi pengaturan Tor dan menghapus data penjelajahan pribadi dengan cepat dan mudah.
torbutton.popup.external.title = Unduh sebuah tipe file eksternal?
torbutton.popup.external.app = Browser Tor tidak dapat menampilkan file ini. Anda butuh aplikasi lain untuk membukanya\n
torbutton.popup.external.note = Beberapa tipe file dapat menyebabkan aplikasi terkoneksi ke internet tanpa menggunakan Tor\n\n
-torbutton.popup.external.suggest = Agar aman, sebaiknya anda hanya membuka file selagi offline, atau gunakan Tor Live CD seperti Tails.\n
+torbutton.popup.external.suggest = Agar aman, sebaiknya anda hanya membuka file selagi offline, atau gunakan Live CD Tor seperti Tails.\n
torbutton.popup.launch = Unduh file
torbutton.popup.cancel = Batal
-torbutton.popup.dontask = Secara otomatis file-file akan di unduh mulai sekarang
-torbutton.popup.no_newnym = Torbution tidak dapat memberikan Anda identitas baru secara aman. Torbutton tidak memiliki akses terhadap Tor Control Port. ⏎⏎ Apakah Anda sedang menjalankan paket browser Tor?
+torbutton.popup.dontask = File-file akan diunduh secara otomatis mulai dari sekarang
+torbutton.popup.no_newnym = Torbution tidak dapat memberikan Anda identitas baru secara aman. Torbutton tidak memiliki akses terhadap Tor Control Port. Apakah Anda sedang menjalankan paket browser Tor?
torbutton.security_settings.menu.title = Pengaturan Keamanan
-torbutton.title.prompt_torbrowser = Important Torbutton Information
-torbutton.popup.prompt_torbrowser = Torbutton works differently now: you can't turn it off any more.\n\nWe made this change because it isn't safe to use Torbutton in a browser that's also used for non-Tor browsing. There were too many bugs there that we couldn't fix any other way.\n\nIf you want to keep using Firefox normally, you should uninstall Torbutton and download Tor Browser Bundle. The privacy properties of Tor Browser are also superior to those of normal Firefox, even when Firefox is used with Torbutton.\n\nTo remove Torbutton, go to Tools->Addons->Extensions and then click the Remove button next to Torbutton.
-torbutton.popup.short_torbrowser = Important Torbutton Information!\n\nTorbutton is now always enabled.\n\nClick on the Torbutton for more information.
+torbutton.title.prompt_torbrowser = Informasi penting Torbutton
+torbutton.popup.prompt_torbrowser = Torbutton bekerja secara berbeda sekarang: Anda tidak dapat mematikannya lagi.\n\nKami membuat perubahan ini karena tidak aman menggunakan Torbutton di browser yang juga digunakan untuk penjelajahan non-Tor. Ada terlalu banyak bug di sana yang tidak dapat kami perbaiki dengan cara lain.\n\nJika Anda ingin tetap menggunakan Firefox secara normal, Anda harus menghapus Torbutton dan mengunduh Tor Browser Bundle. Properti privasi Tor Browser juga lebih unggul dari Firefox biasa, bahkan ketika Firefox digunakan dengan Torbutton.\n\nUntuk menghapus Torbutton, buka Tools->Addons->Extensions dan kemudian klik tombol Remove di sebelah Torbutton.
+torbutton.popup.short_torbrowser = Informasi Penting Torbutton!\n\nTorbutton sekarang selalu diaktifkan.\n\nKlik pada Torbutton untuk informasi lebih lanjut.
-torbutton.popup.confirm_plugins = Plugins such as Flash can harm your privacy and anonymity.\n\nThey can also bypass Tor to reveal your current location and IP address.\n\nAre you sure you want to enable plugins?\n\n
+torbutton.popup.confirm_plugins = Plugin seperti Flash dapat membahayakan privasi dan anonimitas Anda.\n\nMereka juga dapat melewati Tor untuk mengungkapkan lokasi dan alamat IP Anda saat ini.\n\nApakah Anda yakin ingin mengaktifkan plugin?
torbutton.popup.never_ask_again = Jangan pernah ditanyakan kembali
-torbutton.popup.confirm_newnym = Tor Browser akan menutup semua jendela dan tab. Semua sesi website akan terhapus.\n\nJalankan ulang Tor Browser untuk\n\n
+torbutton.popup.confirm_newnym = Browser Tor akan menutup semua jendela dan tab. Semua sesi website akan terhapus.\n\nJalankan ulang Tor Browser untuk\n\n
-torbutton.maximize_warning = Maksimalkan Browser Tor dapat mengizinkan website untuk menentukan ukuran monitor anda, yang dapat digunakan untuk track/jalur anda. kami menyarankan bahwa nda meninggalkan windows browser Tor dalam ukuran asli default nya
+torbutton.maximize_warning = Maksimalkan Browser Tor dapat mengizinkan website untuk menentukan ukuran monitor anda, yang dapat digunakan untuk melacak anda. kami menyarankan bahwa anda meninggalkan windows browser Tor dalam ukuran asli default nya
# Canvas permission prompt. Strings are kept here for ease of translation.
-canvas.siteprompt=Situs ini (%S) butuh untuk mengekstrak data gambar HTML5 , yang mungkin akan mengetahui identitas komputer anda.\n\nApakah anda mengizinkan Tor Browser untuk mengekstrak data gambar HTML5 di website ini?
-canvas.notNow=Tidak untuk Sekarang
+canvas.siteprompt=Situs ini (%S) butuh untuk mengekstrak data gambar HTML5 , yang mungkin akan mengetahui identitas komputer anda.\n\nApakah Tor Browser perlu mengizinkan website ini untuk mengekstrak data gambar HTML5?
+canvas.notNow=Tidak Sekarang
canvas.notNowAccessKey=N
canvas.allow=Izinkan kedepannya
canvas.allowAccessKey=A
@@ -44,14 +44,14 @@ canvas.neverAccessKey=e
# LOCALIZATION NOTE: %S is the application name.
profileProblemTitle=%S Profile bermasalah
profileReadOnly=Anda tidak dapat menjalankan %S dari Sistem File Read only. Silakan copy %S ke lokasi lain sebelum mencoba menggunakannya
-profileReadOnlyMac=Anda tidak bisa menjalankan %S dari File sistem read-only . Silakan copy %S ke desktop anda atau folder aplikasi sebelum mencoba menggunakannya.
+profileReadOnlyMac=Anda tidak bisa menjalankan %S dari File sistem read-only. Silakan copy %S ke desktop anda atau folder aplikasi sebelum mencoba menggunakannya.
profileAccessDenied=%S tidak memiliki izin untuk mengakses profile .Silakan atur perizinan sistem file anda dan coba lagi .
profileMigrationFailed=Migrasi dari profil %S gagal.\nSetting baru akan digunakan.
# "Downloading update" string for the hamburger menu (see #28885).
# This string is kept here for ease of translation.
# LOCALIZATION NOTE: %S is the application name.
-updateDownloadingPanelUILabel=Mengunduh %S memperbarui
+updateDownloadingPanelUILabel=Mengunduh %S pembaruan
# .Onion Page Info prompt. Strings are kept here for ease of translation.
pageInfo_OnionEncryptionWithBitsAndProtocol=Koneksi terenkripsi (Layanan Onion, %1$S, %2$S bit kunci, %3$S)
@@ -60,97 +60,97 @@ pageInfo_OnionName=Nama Onion:
# Onion services strings. Strings are kept here for ease of translation.
onionServices.learnMore=Pelajari Selengkapnya
-onionServices.errorPage.browser=Peramban
+onionServices.errorPage.browser=Browser
onionServices.errorPage.network=Jaringan
onionServices.errorPage.onionSite=Onionsite
# LOCALIZATION NOTE: In the longDescription strings, %S will be replaced with
# an error code, e.g., 0xF3.
# Tor SOCKS error 0xF0:
onionServices.descNotFound.pageTitle=Masalah Memuat Onionsite
-onionServices.descNotFound.header=Onionsite Tidak di temukan
-onionServices.descNotFound=The most likely cause is that the onionsite is offline. Contact the onionsite administrator.
-onionServices.descNotFound.longDescription=Details: %S — The requested onion service descriptor can't be found on the hashring and therefore the service is not reachable by the client.
+onionServices.descNotFound.header=Onionsite Tidak ditemukan
+onionServices.descNotFound=Penyebab yang paling mungkin adalah bahwa situs onion sedang offline. Hubungi administrator situs onion.
+onionServices.descNotFound.longDescription=Detail: %S — Deskriptor layanan onion yang diminta tidak dapat ditemukan pada hashring dan oleh karena itu layanan tidak dapat dijangkau oleh klien.
# Tor SOCKS error 0xF1:
onionServices.descInvalid.pageTitle=Masalah Memuat Onionsite
-onionServices.descInvalid.header=Onionsite Cannot Be Reached
-onionServices.descInvalid=The onionsite is unreachable due an internal error.
-onionServices.descInvalid.longDescription=Details: %S — The requested onion service descriptor can't be parsed or signature validation failed.
+onionServices.descInvalid.header=Onionsite Tidak bisa dijangkau
+onionServices.descInvalid=Onionsite tidak dapat dijangkau karena ada kesalahan internal.
+onionServices.descInvalid.longDescription=Detail: %S — Deskriptor layanan onion yang diminta tidak dapat diuraikan atau validasi tanda tangan gagal.
# Tor SOCKS error 0xF2:
onionServices.introFailed.pageTitle=Masalah Memuat Onionsite
-onionServices.introFailed.header=Onionsite Has Disconnected
-onionServices.introFailed=The most likely cause is that the onionsite is offline. Contact the onionsite administrator.
-onionServices.introFailed.longDescription=Details: %S — Introduction failed, which means that the descriptor was found but the service is no longer connected to the introduction point. It is likely that the service has changed its descriptor or that it is not running.
+onionServices.introFailed.header=Onionsite Terputus
+onionServices.introFailed=Penyebab yang paling mungkin adalah bahwa situs onion sedang offline. Hubungi administrator situs onion.
+onionServices.introFailed.longDescription=Detail: %S — perkenalan gagal, yang berarti bahwa deskriptor ditemukan tetapi layanan tidak lagi terhubung ke titik perkenalan. Kemungkinan layanan telah mengubah deskriptornya atau sedang tidak berjalan.
# Tor SOCKS error 0xF3:
onionServices.rendezvousFailed.pageTitle=Masalah Memuat Onionsite
-onionServices.rendezvousFailed.header=Unable to Connect to Onionsite
-onionServices.rendezvousFailed=The onionsite is busy or the Tor network is overloaded. Try again later.
-onionServices.rendezvousFailed.longDescription=Details: %S — The client failed to rendezvous with the service, which means that the client was unable to finalize the connection.
+onionServices.rendezvousFailed.header=Tidak bisa Terhubung ke Onionsite
+onionServices.rendezvousFailed=Onionsite sedang sibuk atau jaringan Tor sedang kelebihan beban. Silahkan coba lagi.
+onionServices.rendezvousFailed.longDescription=Detail: %S — Klien gagal terhubung dengan layanan, yang berarti klien tidak dapat menyelesaikan koneksi.
# Tor SOCKS error 0xF4:
-onionServices.clientAuthMissing.pageTitle=Authorization Required
-onionServices.clientAuthMissing.header=Onionsite Requires Authentication
-onionServices.clientAuthMissing=Access to the onionsite requires a key but none was provided.
-onionServices.clientAuthMissing.longDescription=Details: %S — The client downloaded the requested onion service descriptor but was unable to decrypt its content because client authorization information is missing.
+onionServices.clientAuthMissing.pageTitle=Dibutuhkan otorisasi
+onionServices.clientAuthMissing.header=Onionsite Membutuhkan Otorisasi
+onionServices.clientAuthMissing=Akses ke situs onion memerlukan key tetapi tidak ditemukan.
+onionServices.clientAuthMissing.longDescription=Detail: %S — Klien mengunduh deskriptor layanan onion yang diminta tetapi tidak dapat mendekripsi kontennya karena informasi otorisasi klien hilang.
# Tor SOCKS error 0xF5:
-onionServices.clientAuthIncorrect.pageTitle=Authorization Failed
-onionServices.clientAuthIncorrect.header=Onionsite Authentication Failed
-onionServices.clientAuthIncorrect=The provided key is incorrect or has been revoked. Contact the onionsite administrator.
-onionServices.clientAuthIncorrect.longDescription=Details: %S — The client was able to download the requested onion service descriptor but was unable to decrypt its content using the provided client authorization information. This may mean that access has been revoked.
+onionServices.clientAuthIncorrect.pageTitle=Otorisasi Gagal
+onionServices.clientAuthIncorrect.header=Otorisasi Onionsite Gagal
+onionServices.clientAuthIncorrect=Key yang diberikan salah atau telah dihapus. Hubungi administrator situs onion.
+onionServices.clientAuthIncorrect.longDescription=Detail: %S — Klien dapat mengunduh deskriptor layanan onion yang diminta tetapi tidak dapat mendekripsi kontennya menggunakan informasi otorisasi klien yang disediakan. Ini mungkin berarti bahwa akses telah dicabut.
# Tor SOCKS error 0xF6:
onionServices.badAddress.pageTitle=Masalah Memuat Onionsite
-onionServices.badAddress.header=Invalid Onionsite Address
-onionServices.badAddress=The provided onionsite address is invalid. Please check that you entered it correctly.
-onionServices.badAddress.longDescription=Details: %S — The provided .onion address is invalid. This error is returned due to one of the following reasons: the address checksum doesn't match, the ed25519 public key is invalid, or the encoding is invalid.
+onionServices.badAddress.header=Alamat Onionsite Salah
+onionServices.badAddress=Alamat situs onion yang diberikan tidak valid. Harap periksa apakah Anda sudah memasukkannya dengan benar.
+onionServices.badAddress.longDescription=Detail: %S — Alamat .onion yang diberikan tidak valid. Kesalahan ini dikembalikan karena salah satu alasan berikut: alamat checksum tidak cocok, key publik ed25519 tidak valid, atau encoding tidak valid.
# Tor SOCKS error 0xF7:
onionServices.introTimedOut.pageTitle=Masalah Memuat Onionsite
-onionServices.introTimedOut.header=Onionsite Circuit Creation Timed Out
-onionServices.introTimedOut=Failed to connect to the onionsite, possibly due to a poor network connection.
-onionServices.introTimedOut.longDescription=Details: %S — The connection to the requested onion service timed out while trying to build the rendezvous circuit.
+onionServices.introTimedOut.header=Waktu Pembuatan Sirkuit Onionsite Habis
+onionServices.introTimedOut=Gagal terhubung ke situs onion, mungkin karena koneksi jaringan yang buruk.
+onionServices.introTimedOut.longDescription=Detail: %S — Sambungan ke layanan onion yang dituju waktunya sudah habis disaat mencoba membangun sirkuit pertemuan.
#
# LOCALIZATION NOTE: %S will be replaced with the .onion address.
-onionServices.authPrompt.description2=%S is requesting that you authenticate.
-onionServices.authPrompt.keyPlaceholder=Enter your private key for this onion service
+onionServices.authPrompt.description2=%S meminta anda mengautentikasi.
+onionServices.authPrompt.keyPlaceholder=Masukkan private key anda untuk layanan onion ini
onionServices.authPrompt.done=Selesai
onionServices.authPrompt.doneAccessKey=d
-onionServices.authPrompt.invalidKey=Please enter a valid key (52 base32 characters or 44 base64 characters)
-onionServices.authPrompt.failedToSetKey=Unable to configure Tor with your key
-onionServices.authPreferences.header=Onion Services Authentication
-onionServices.authPreferences.overview=Some onion services require that you identify yourself with a key (a kind of password) before you can access them.
-onionServices.authPreferences.savedKeys=Saved Keys…
-onionServices.authPreferences.dialogTitle=Onion Service Keys
-onionServices.authPreferences.dialogIntro=Keys for the following onionsites are stored on your computer
-onionServices.authPreferences.onionSite=Onionsitus
-onionServices.authPreferences.onionKey=Kunci
+onionServices.authPrompt.invalidKey=Harap masukkan key yang valid (52 karakter base32 atau 44 karakter base64)
+onionServices.authPrompt.failedToSetKey=Tidak dapat mengonfigurasi Tor dengan key Anda
+onionServices.authPreferences.header=Otentikasi Layanan Onion
+onionServices.authPreferences.overview=Beberapa layanan onion mengharuskan anda mengidentifikasi diri anda dengan key (semacam kata sandi) sebelum anda dapat mengaksesnya.
+onionServices.authPreferences.savedKeys=Key Tersimpan…
+onionServices.authPreferences.dialogTitle=Key Layanan Onion
+onionServices.authPreferences.dialogIntro=Kunci untuk situs onion berikut disimpan di komputer Anda
+onionServices.authPreferences.onionSite=Onionsite
+onionServices.authPreferences.onionKey=Key
onionServices.authPreferences.remove=Hapus
onionServices.authPreferences.removeAll=Hapus semua
-onionServices.authPreferences.failedToGetKeys=Unable to retrieve keys from tor
-onionServices.authPreferences.failedToRemoveKey=Unable to remove key
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
-onionServices.v2Deprecated.tryAgain=Got it
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.authPreferences.failedToGetKeys=Tidak dapat mengambil key dari tor
+onionServices.authPreferences.failedToRemoveKey=Tidak bisa menghapus key
+onionServices.v2Deprecated.pageTitle=Peringatan Penghentian Situs Onion V2
+onionServices.v2Deprecated.header=Situs Onion Versi 2 akan segera dihentikan
+onionServices.v2Deprecated=Situs onion ini tidak akan dapat dijangkau dalam waktu dekat. Silakan hubungi administrator situs dan minta mereka untuk memperbaharuinya.
+onionServices.v2Deprecated.longDescription=Tor mengakhiri dukungannya untuk layanan onion versi 2 mulai Juli 2021, dan situs onion ini tidak lagi dapat dijangkau di alamat ini. Jika Anda adalah administrator situs, segera tingkatkan ke layanan onion versi 3.
+onionServices.v2Deprecated.tryAgain=Mengerti
+onionServices.v2Deprecated.tooltip=Situs onion ini sudah tidak dapat dijangkau kembali dikemudian hari
# Onion-Location strings.
-onionLocation.alwaysPrioritize=Always Prioritize Onions
-onionLocation.alwaysPrioritizeAccessKey=P
+onionLocation.alwaysPrioritize=Selalu Utamakan Onion
+onionLocation.alwaysPrioritizeAccessKey=a
onionLocation.notNow=Tidak untuk Sekarang
onionLocation.notNowAccessKey=n
-onionLocation.description=There's a more private and secure version of this site available over the Tor network via onion services. Onion services help website publishers and their visitors defeat surveillance and censorship.
-onionLocation.tryThis=Try Onion Services
-onionLocation.onionAvailable=.onion available
+onionLocation.description=Ada versi yang lebih pribadi dan aman dari situs ini yang tersedia melalui jaringan Tor melalui layanan onion. Layanan onion membantu penerbit situs web dan pengunjung mereka melewati pengawasan dan penyensoran.
+onionLocation.tryThis=Coba Layanan Onion
+onionLocation.onionAvailable=.onion tersedia
onionLocation.learnMore=Pelajari Selengkapnya...
onionLocation.always=Selalu
onionLocation.askEverytime=Tanyakan setiap saat
-onionLocation.prioritizeOnionsDescription=Prioritize .onion sites when known.
+onionLocation.prioritizeOnionsDescription=Prioritaskan situs .onion jika tersedia.
onionLocation.onionServicesTitle=Layanan Onion
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
-cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
-cryptoSafetyPrompt.whatCanHeading=What can you do about it?
-cryptoSafetyPrompt.whatCanBody=You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning.
+cryptoSafetyPrompt.cryptoWarning=Alamat mata uang kripto (%S) telah disalin dari situs web yang tidak aman. Itu bisa saja dimodifikasi.
+cryptoSafetyPrompt.whatCanHeading=Apa yang dapat Anda lakukan?
+cryptoSafetyPrompt.whatCanBody=Anda dapat mencoba menghubungkan kembali dengan sirkuit baru untuk membuat koneksi yang aman, atau menerima risiko dan abaikan peringatan ini.
cryptoSafetyPrompt.learnMore=Pelajari Selengkapnya
-cryptoSafetyPrompt.primaryAction=Reload Tab with a New Circuit
+cryptoSafetyPrompt.primaryAction=Muat Ulang Tab dengan Sirkuit Baru
cryptoSafetyPrompt.primaryActionAccessKey=R
-cryptoSafetyPrompt.secondaryAction=Dismiss Warning
+cryptoSafetyPrompt.secondaryAction=Abaikan Peringatan
cryptoSafetyPrompt.secondaryActionAccessKey=B
diff --git a/chrome/locale/is/torbutton.dtd b/chrome/locale/is/torbutton.dtd
index 7b013603..93c97942 100644
--- a/chrome/locale/is/torbutton.dtd
+++ b/chrome/locale/is/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Sérsniðnar kjörstillingar vafrans þíns valda mjög óvenjulegum öryggisstillingum. Til að uppfylla sem best öryggi og gagnaleynd, mælum við með því að þú veljir eitt af sjálfgefnum öryggisstigum.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Frumstilla á sjálfgefið">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Ítarlegar öryggisstillingar…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor-rás">
<!ENTITY torbutton.circuit_display.new_circuit "Ný rás fyrir þetta vefsvæði">
diff --git a/chrome/locale/it/aboutTor.dtd b/chrome/locale/it/aboutTor.dtd
index c3b5bdd3..29d6ae12 100644
--- a/chrome/locale/it/aboutTor.dtd
+++ b/chrome/locale/it/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "VIA\nDAI\nMEI\nDATI">
<!ENTITY aboutTor.yec.motto "La privacy è un diritto umano">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/it/torbutton.dtd b/chrome/locale/it/torbutton.dtd
index 3a0edd1e..de494ab0 100644
--- a/chrome/locale/it/torbutton.dtd
+++ b/chrome/locale/it/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Le tue impostazioni personalizzate del browser sembrano avere preferenze di sicurezza insolite. Per motivi di sicurezza e privacy, ti consigliamo di scegliere uno dei livelli di sicurezza predefiniti.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Ripristina Impostazioni Iniziali">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Impostazioni di Sicurezza Avanzate...">
+<!ENTITY torbutton.prefs.sec_change "Cambia…">
<!ENTITY torbutton.circuit_display.title "Circuito Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Nuovo circuito per questo sito">
diff --git a/chrome/locale/it/torbutton.properties b/chrome/locale/it/torbutton.properties
index d3dd932f..a437a519 100644
--- a/chrome/locale/it/torbutton.properties
+++ b/chrome/locale/it/torbutton.properties
@@ -124,9 +124,9 @@ onionServices.authPreferences.remove=Rimuovi
onionServices.authPreferences.removeAll=Rimuovi tutte
onionServices.authPreferences.failedToGetKeys=Impossibile recuperare le chiavi da Tor
onionServices.authPreferences.failedToRemoveKey=Impossibile rimuovere la chiave
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
+onionServices.v2Deprecated.pageTitle=Avviso di obsolescenza siti Onion V2
+onionServices.v2Deprecated.header=I siti Onion versione 2 verranno presto deprecati
+onionServices.v2Deprecated=Questo sito onion presto non sarà raggiungibile. Contatta l'amministratore del sito e incoraggialo ad aggiornarlo.
onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
onionServices.v2Deprecated.tryAgain=Ho capito
onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
diff --git a/chrome/locale/ja/aboutTor.dtd b/chrome/locale/ja/aboutTor.dtd
index f579c67b..7a7d2dc9 100644
--- a/chrome/locale/ja/aboutTor.dtd
+++ b/chrome/locale/ja/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "データ\nに\n手を\n触れるな">
<!ENTITY aboutTor.yec.motto "プライバシーは人権です">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Your donation will be matched by Friends of Tor, up to $150,000.">
+<!ENTITY aboutTor.yec.donationMatch "あなたが寄付した額と同額を、Torのパートナーも寄付します (最大150,000ドル)">
diff --git a/chrome/locale/ja/torbutton.dtd b/chrome/locale/ja/torbutton.dtd
index ec5e9f1f..301a3d40 100644
--- a/chrome/locale/ja/torbutton.dtd
+++ b/chrome/locale/ja/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "あなたのブラウザーにおけるカスタム設定はセキュリティ結果に影響を及ぼしません。セキュリティとプライバシーに関してはデフォルトのセキュリティレベルのひとつを選択することをおすすめいたします。">
<!ENTITY torbutton.prefs.sec_restore_defaults "デフォルトにもどす">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "詳細セキュリティ設定…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor 回線">
<!ENTITY torbutton.circuit_display.new_circuit "このサイト用の回線を再構築">
diff --git a/chrome/locale/ja/torbutton.properties b/chrome/locale/ja/torbutton.properties
index 6f917832..b28b0185 100644
--- a/chrome/locale/ja/torbutton.properties
+++ b/chrome/locale/ja/torbutton.properties
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=解除
onionServices.authPreferences.removeAll=すべて削除
onionServices.authPreferences.failedToGetKeys=Tor から鍵を取得できません
onionServices.authPreferences.failedToRemoveKey=鍵を削除できません
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
+onionServices.v2Deprecated.pageTitle=V2 Onion サイトの非推奨についての警告
+onionServices.v2Deprecated.header=もうすぐバージョン 2 Onion サイトは非推奨になります
+onionServices.v2Deprecated=この Onion サイトはもうすぐ非推奨になります。サイト管理者に連絡し、アップグレードを依頼してください。
onionServices.v2Deprecated.longDescription=Tor は、バージョン 2 の Onion サービスのサポートを 2021 年 7 月に終了します。今後、バージョン 2 の Onion サイトには到達できなくなります。あなたがサイト管理者の場合、早急にバージョン 3 の Onion サービスにアップグレードしてください。
onionServices.v2Deprecated.tryAgain=了解
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.tooltip=この Onion サイトはもうすぐ非推奨になります
# Onion-Location strings.
onionLocation.alwaysPrioritize=常に Onion を優先する
diff --git a/chrome/locale/ka/aboutTor.dtd b/chrome/locale/ka/aboutTor.dtd
index 24a4d98d..14c2db32 100644
--- a/chrome/locale/ka/aboutTor.dtd
+++ b/chrome/locale/ka/aboutTor.dtd
@@ -22,12 +22,12 @@
<!ENTITY aboutTor.torbrowser_user_manual.accesskey "ხ">
<!ENTITY aboutTor.torbrowser_user_manual.label "Tor-ბრაუზერის სახელმძღვანელო">
-<!ENTITY aboutTor.tor_mission.label "Tor-პროექტი წარმოადგენს 501(c)(3) არამომგებიან დაწესებულებას, რომელიც ხელს უწყობს ადამიანის უფლებების დაცვისა და თავისუფლების ხარისხის გაუმჯობესებას, უფასო და ღია წყაროს მქონე, ვინაობისა და პირადი მონაცემების გამჟღავნებისგან ასარიდებელი საშუალებების შექმნითა და გავრცელებით, მათზე შეუზღუდავი წვდომისა და გამოყენების უზრუნველყოფით, შემდგომ კი მათთან დაკავშირე
ბით მეცნიერული გაგებისა და საზოგადოების ცნობიერების დონის ამაღლებით.">
+<!ENTITY aboutTor.tor_mission.label "Tor-პროექტი წარმოადგენს 501(c)(3) არამომგებიან დაწესებულებას, რომელიც ხელს უწყობს ადამიანის უფლებების დაცვისა და თავისუფლების ხარისხის გაუმჯობესებას, უფასო და ღია წყაროს მქონე, ვინაობისა და პირადი მონაცემების გამჟღავნებისგან ასარიდებელი საშუალებების შექმნითა და გავრცელებით, მათზე შეუზღუდავი წვდომისა და გამოყენების უზრუნველყოფით, შემდგომ კი მათთან დაკავშირე
ბით, მეცნიერული გაგებისა და საზოგადოების ცნობიერების დონის ამაღლებით.">
<!ENTITY aboutTor.getInvolved.label "შემოგვიერთდით »">
<!ENTITY aboutTor.newsletter.tagline "მიიღეთ სიახლეები Tor-ისგან, პირდაპირ თქვენს საფოსტო ყუთში.">
<!ENTITY aboutTor.newsletter.link_text "გამოიწერეთ Tor-ის სიახლეები.">
-<!ENTITY aboutTor.donationBanner.freeToUse "Tor უფასოა, თქვენნაირი ადამიანების შემოწირულობების დამსახურებით.">
+<!ENTITY aboutTor.donationBanner.freeToUse "Tor უფასოა, თქვენნაირი ადამიანების შემოწირულობების წყალობით.">
<!ENTITY aboutTor.donationBanner.buttonA "გაიღეთ თანხა">
<!-- Year end campaign strings -->
@@ -47,8 +47,8 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
-<!ENTITY aboutTor.yec.motto "პირადულობა ადამიანის ძირითადი უფლებაა">
+<!ENTITY aboutTor.yec.slogan "ᲮᲔᲚᲔᲑᲘ\nᲨᲝᲠᲡ ᲩᲔᲛᲘ\nᲞᲘᲠᲐᲓᲘ\nᲡᲘᲕᲠᲪᲘᲓᲐᲜ">
+<!ENTITY aboutTor.yec.motto "პირადულობა ადამიანის ძირეული უფლებაა">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Your donation will be matched by Friends of Tor, up to $150,000.">
+<!ENTITY aboutTor.yec.donationMatch "თქვენი შემოწირულობა გაორმაგდება Tor-ის მეგობრების მიერ, $150,000-ამდე.">
diff --git a/chrome/locale/ka/browserOnboarding.properties b/chrome/locale/ka/browserOnboarding.properties
index 978e8d47..3453ba49 100644
--- a/chrome/locale/ka/browserOnboarding.properties
+++ b/chrome/locale/ka/browserOnboarding.properties
@@ -13,14 +13,14 @@ onboarding.tour-tor-privacy.description=Tor-ბრაუზერი აცა
onboarding.tour-tor-privacy.button=იხილეთ Tor-ქსელი
onboarding.tour-tor-network=Tor-ქსელი
-onboarding.tour-tor-network.title=გამოიყენეთ, ერთპიროვნული მართვისგან დაცული ქსელი.
+onboarding.tour-tor-network.title=ერთპიროვნული მართვისგან დაცული ქსელი.
onboarding.tour-tor-network.description=Tor-ბრაუზერით უკავშირდებით Tor-ქსელს, რომლის მუშაობასაც უზრუნველყოფს ათასობით მოხალისე, მთელი მსოფლიოს მასშტაბით. განსხვავებით VPN-ისგან, აქ არ გიწევთ ვინმე საერთო მმართველის ან დაწესებულების ნდობა, ინტერნეტით ვინაობის გაუმჟღავნებლად სარგებლობისთვის.
onboarding.tour-tor-network.description-para2=სიახლე: Tor-ქსელის გამართვა, აგრეთვე, ხიდების მოთხოვნა, Tor-ის შეზღუდვის პირობებში, ახლა უკვე შეგიძლიათ პარამეტრებიდან.
onboarding.tour-tor-network.action-button=გამართეთ Tor-ქსელის პარამეტრები
onboarding.tour-tor-network.button=იხილეთ წრედის არე
onboarding.tour-tor-circuit-display=წრედის არე
-onboarding.tour-tor-circuit-display.title=იხილეთ თქვენი არხი.
+onboarding.tour-tor-circuit-display.title=იხილეთ თქვენი კავშირის არხი.
onboarding.tour-tor-circuit-display.description=თითოეულ მისამართზე გადასვლისას, მიმოცვლილი მონაცემები სრულად გარდაიქმნება და იშიფრება, მსოფლიოს ნებისმიერ წერტილიდან შემთხვევით შერჩეული სამი Tor-გადამცემით შექმნილ წრედში. ვებსაიტებს არ შეეძლება დადგენა, საიდან უკავშირდებით. ახალი წრედის მოთხოვნისთვის, წრედის არეში დაწკაპეთ „ახალი წრედი ამ საიტისთვის“.
onboarding.tour-tor-circuit-display.button=არხის ნახვა
onboarding.tour-tor-circuit-display.next-button=იხილეთ უსაფრთხოება
@@ -28,7 +28,7 @@ onboarding.tour-tor-circuit-display.next-button=იხილეთ უსაფ
onboarding.tour-tor-security=უსაფრთხოება
onboarding.tour-tor-security.title=მოარგეთ საკუთარ მოთხოვნილებებს
onboarding.tour-tor-security.description=ჩვენ ასევე გთავაზობთ დამატებით პარამეტრებს, ბრაუზერის უსაფრთხოების კიდევ უფრო მეტად ასამაღლებლად. ჩვენი უსაფრთხოების პარამეტრები, საშუალებას გაძლევთ შეზღუდოთ გვერდის ის ნაწილები, რომლებიც თქვენს კომპიუტერზე შეტევისთვის შეიძლება გამოიყენონ. დაწკაპეთ ქვემოთ და იხილეთ ამ პარამეტრების შესახებ ვრცლად.
-onboarding.tour-tor-security.description-suffix=გაითვალისწინეთ: ნაგულისხმევად, NoScript და HTTPS Everywhere არაა წარმოდგენილი ხელსაწყოთა ზოლზე, თუმცა სურვილისამებრ, შეგიძლიათ მათი მანდ განთავსება.
+onboarding.tour-tor-security.description-suffix=გაითვალისწინეთ: ნაგულისხმევად, NoScript და HTTPS Everywhere არაა წარმოდგენილი ხელსაწყოთა ზოლზე, თუმცა სურვილისამებრ, შეგიძლიათ იქვე განათავსოთ.
onboarding.tour-tor-security-level.button=უსაფრთხოების დონის ნახვა
onboarding.tour-tor-security-level.next-button=იხილეთ გამოყენების რჩევები
diff --git a/chrome/locale/ka/torbutton.dtd b/chrome/locale/ka/torbutton.dtd
index 4d1ea917..d0be6d2c 100644
--- a/chrome/locale/ka/torbutton.dtd
+++ b/chrome/locale/ka/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "თქვენ მიერ მითითებული პარამეტრები ბრაუზერში, არაა მისაღები უსაფრთხოებისთვის. პირადი მონაცემების სათანადოდ დაცვის უზრუნველსაყოფად, გირჩევთ შეარჩიოთ უსაფრთხოების ნაგულისხმევი დონეებიდან რომელიმე.">
<!ENTITY torbutton.prefs.sec_restore_defaults "ნაგულისხმევის აღდგენა">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "უსაფრთხოების დამატებითი პარამ.">
+<!ENTITY torbutton.prefs.sec_change "შეცვლა...">
<!ENTITY torbutton.circuit_display.title "Tor-წრედი">
<!ENTITY torbutton.circuit_display.new_circuit "ახალი წრედი ამ საიტისთვის">
diff --git a/chrome/locale/ka/torbutton.properties b/chrome/locale/ka/torbutton.properties
index bd3a03ec..2939a041 100644
--- a/chrome/locale/ka/torbutton.properties
+++ b/chrome/locale/ka/torbutton.properties
@@ -136,7 +136,7 @@ onionLocation.alwaysPrioritize=ყოველთვის Onions
onionLocation.alwaysPrioritizeAccessKey=ვ
onionLocation.notNow=ახლა არა
onionLocation.notNowAccessKey=ა
-onionLocation.description=არსებობს მეტად პირადი და დაცული ვერსია ამ საიტის Tor-ქსელში, onion-მომსახურების სახით. Onion-მომსახურებები ეხმარება საიტის მფლობელებსა და მნახველებს, თვალის დევნებისა და ცენზურის არიდებაში.
+onionLocation.description=ამ საიტის მეტად პირადი და დაცული ვერსია ხელმისაწვდომია Tor-ქსელში, Onion-მომსახურების სახით. Onion-მომსახურებით, საიტის მფლობელებსა და მნახველებს, საშუალება ეძლევათ აირიდონ თვალის დევნება და ცენზურა.
onionLocation.tryThis=სცადეთ Onion-მომსახურებები
onionLocation.onionAvailable=.onion ხელმისაწვდომია
onionLocation.learnMore=იხილეთ ვრცლად...
diff --git a/chrome/locale/ko/torbutton.dtd b/chrome/locale/ko/torbutton.dtd
index 95a45a0d..7cc9f357 100644
--- a/chrome/locale/ko/torbutton.dtd
+++ b/chrome/locale/ko/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "사용자 지정 브라우저 설정으로 인해 비정상적인 보안 설정이 발생했습니다. 보안 및 개인정보 보호를 위하여 보안 수준의 기본값 중 하나를 선택하는 것이 좋습니다.">
<!ENTITY torbutton.prefs.sec_restore_defaults "기본값으로 복구">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "고급 보안 설정">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor 우회로">
<!ENTITY torbutton.circuit_display.new_circuit "이 사이트에서 새로운 서킷을 재구축">
diff --git a/chrome/locale/lt/aboutTor.dtd b/chrome/locale/lt/aboutTor.dtd
index c9702032..7885a6be 100644
--- a/chrome/locale/lt/aboutTor.dtd
+++ b/chrome/locale/lt/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "PATRAUKITE\nRANKAS\nNUO\nMANO\nDUOMENŲ">
<!ENTITY aboutTor.yec.motto "Privatumas yra žmogaus teisė">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Your donation will be matched by Friends of Tor, up to $150,000.">
+<!ENTITY aboutTor.yec.donationMatch "„Friends of Tor“ paaukos tiek pat, kiek ir jūs, iki $150000.">
diff --git a/chrome/locale/lt/torbutton.dtd b/chrome/locale/lt/torbutton.dtd
index 4303936f..4a641e6d 100644
--- a/chrome/locale/lt/torbutton.dtd
+++ b/chrome/locale/lt/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Jūsų pasirinktinės naršyklės nuostatos sąlygojo neįprastus saugumo nustatymus. Dėl saugumo ir privatumo priežasčių, rekomenduojame jums pasirinkti vieną iš numatytųjų saugumo lygių.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Atkurti numatytuosius">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Išplėstiniai saugumo nustatymai…">
+<!ENTITY torbutton.prefs.sec_change "Pakeisti...">
<!ENTITY torbutton.circuit_display.title "Tor grandinė">
<!ENTITY torbutton.circuit_display.new_circuit "Nauja grandinė šiai svetainei">
diff --git a/chrome/locale/lt/torbutton.properties b/chrome/locale/lt/torbutton.properties
index f87cf465..56c1afdb 100644
--- a/chrome/locale/lt/torbutton.properties
+++ b/chrome/locale/lt/torbutton.properties
@@ -69,42 +69,42 @@ onionServices.errorPage.onionSite=Onion svetainės
onionServices.descNotFound.pageTitle=Problema įkeliant onion svetainę
onionServices.descNotFound.header=Onion svetainė nerasta
onionServices.descNotFound=Labiausiai tikėtina priežastis ta, kad onion svetainė yra nepasiekiama. Susisiekite su onion svetainės administratoriumi.
-onionServices.descNotFound.longDescription=Details: %S — The requested onion service descriptor can't be found on the hashring and therefore the service is not reachable by the client.
+onionServices.descNotFound.longDescription=Išsami informacija: %S – maišos sistemoje nerastas prašomo onion serviso deskriptoriaus, todėl klientui servisas nepasiekiamas.
# Tor SOCKS error 0xF1:
onionServices.descInvalid.pageTitle=Problema įkeliant onion svetainę
onionServices.descInvalid.header=Onion svetainė nepasiekiama
onionServices.descInvalid=Onion svetainė nepasiekiama dėl vidinės klaidos.
-onionServices.descInvalid.longDescription=Details: %S — The requested onion service descriptor can't be parsed or signature validation failed.
+onionServices.descInvalid.longDescription=Išsami informacija: %S – prašomo obion serviso deskriptoriaus negalima išanalizuoti arba nepavyko patvirtinti parašo.
# Tor SOCKS error 0xF2:
onionServices.introFailed.pageTitle=Problema įkeliant onion svetainę
onionServices.introFailed.header=Onion svetainė atsijungė
onionServices.introFailed=Labiausiai tikėtina priežastis ta, kad onion svetainė yra nepasiekiama. Susisiekite su onion svetainės administratoriumi.
-onionServices.introFailed.longDescription=Details: %S — Introduction failed, which means that the descriptor was found but the service is no longer connected to the introduction point. It is likely that the service has changed its descriptor or that it is not running.
+onionServices.introFailed.longDescription=Išsami informacija: %S – Įvadas nepavyko, o tai reiškia, kad deskriptorius buvo rastas, bet servisas nebėra prijungta prie įvado taško. Tikėtina, kad servisas pakeitė savo aprašą arba ji neveikia.
# Tor SOCKS error 0xF3:
onionServices.rendezvousFailed.pageTitle=Problema įkeliant onion svetainę
onionServices.rendezvousFailed.header=Nepavyko prisijungti prie onion svetainės
onionServices.rendezvousFailed=Onion svetainė užimta arba Tor tinklas perkrautas. Pabandykite dar kartą vėliau.
-onionServices.rendezvousFailed.longDescription=Details: %S — The client failed to rendezvous with the service, which means that the client was unable to finalize the connection.
+onionServices.rendezvousFailed.longDescription=Išsami informacija: %S – klientui nepavyko susisiekti su servisu, o tai reiškia, kad klientas negalėjo užbaigti ryšio.
# Tor SOCKS error 0xF4:
onionServices.clientAuthMissing.pageTitle=Reikalingas įgaliojimas
onionServices.clientAuthMissing.header=Onion svetainėje reikalaujamas atpažinimas
onionServices.clientAuthMissing=Norint pasiekti onion svetainę reikalingas raktas, tačiau jis nebuvo suteiktas.
-onionServices.clientAuthMissing.longDescription=Details: %S — The client downloaded the requested onion service descriptor but was unable to decrypt its content because client authorization information is missing.
+onionServices.clientAuthMissing.longDescription=Išsami informacija: %S – klientas atsisiuntė prašomą onion serviso deskriptorių, bet negalėjo iššifruoti jo turinio, nes trūksta kliento prieigos teisės informacijos.
# Tor SOCKS error 0xF5:
onionServices.clientAuthIncorrect.pageTitle=Įgaliojimas nepavyko
onionServices.clientAuthIncorrect.header=Onion svetainės atpažinimas nepavyko
onionServices.clientAuthIncorrect=Pateiktas raktas neteisingas arba buvo panaikintas. Susisiekite su onion svetainės administratoriumi.
-onionServices.clientAuthIncorrect.longDescription=Details: %S — The client was able to download the requested onion service descriptor but was unable to decrypt its content using the provided client authorization information. This may mean that access has been revoked.
+onionServices.clientAuthIncorrect.longDescription=Išsami informacija: %S – klientas galėjo atsisiųsti prašomą onion serviso deskriptorių, bet negalėjo iššifruoti jo turinio naudodamas pateiktą kliento prieigos teisės informaciją. Tai gali reikšti, kad prieiga buvo atšaukta.
# Tor SOCKS error 0xF6:
onionServices.badAddress.pageTitle=Problema įkeliant onion svetainę
onionServices.badAddress.header=Neteisingas onion svetainės adresas
onionServices.badAddress=Pateiktas onion svetainės adresas neteisingas. Įsitikinkite, kad jį įvedėte teisingai.
-onionServices.badAddress.longDescription=Details: %S — The provided .onion address is invalid. This error is returned due to one of the following reasons: the address checksum doesn't match, the ed25519 public key is invalid, or the encoding is invalid.
+onionServices.badAddress.longDescription=Išsami informacija: %S – pateiktas .onion adresas neteisingas. Ši klaida grąžinama dėl vienos iš šių priežasčių: adreso kontrolinė suma nesutampa, ed25519 viešasis raktas neteisingas arba kodavimas neteisingas.
# Tor SOCKS error 0xF7:
onionServices.introTimedOut.pageTitle=Problema įkeliant onion svetainę
onionServices.introTimedOut.header=Baigėsi onion grandinės kūrimui skirtas laikas
onionServices.introTimedOut=Nepavyko prisijungti prie onion svetainės, galbūt dėl silpno tinklo ryšio.
-onionServices.introTimedOut.longDescription=Details: %S — The connection to the requested onion service timed out while trying to build the rendezvous circuit.
+onionServices.introTimedOut.longDescription=Išsami informacija: %S – Bandant sukurti susitikimo grandinę baigėsi ryšio su prašomu onion servisu skirtasis laikas.
#
# LOCALIZATION NOTE: %S will be replaced with the .onion address.
onionServices.authPrompt.description2=%S prašo, kad nustatytumėte savo tapatybę.
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=Šalinti
onionServices.authPreferences.removeAll=Šalinti visus
onionServices.authPreferences.failedToGetKeys=Nepavyko gauti raktų iš Tor
onionServices.authPreferences.failedToRemoveKey=Nepavyko pašalinti raktą
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
+onionServices.v2Deprecated.pageTitle=V2 Onion svetainės naudojimo nutraukimo įspėjimas
+onionServices.v2Deprecated.header=2 versijos onion svetainės netrukus bus nebenaudojamos
+onionServices.v2Deprecated=Ši onion svetainė greitai nebus pasiekiama. Susisiekite su svetainės administratoriumi ir paraginkite jį atsinaujinti.
+onionServices.v2Deprecated.longDescription=Nuo 2021 m. liepos mėn. Tor nutraukia 2 versijos „onion“ servisų palaikymą ir ši onion svetainė šiuo adresu nebebus pasiekiama. Jei esate svetainės administratorius, naujovinkite į 3 versijos onion servisą.
onionServices.v2Deprecated.tryAgain=Supratau
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.tooltip=Ši onion svetainė greitai nebus pasiekiama
# Onion-Location strings.
onionLocation.alwaysPrioritize=Visada teikti pirmenybę Onions
@@ -146,11 +146,11 @@ onionLocation.prioritizeOnionsDescription=Teikti pirmenybę .onion svetainėms,
onionLocation.onionServicesTitle=Onion paslaugos
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
-cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
-cryptoSafetyPrompt.whatCanHeading=What can you do about it?
-cryptoSafetyPrompt.whatCanBody=You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning.
+cryptoSafetyPrompt.cryptoWarning=Kriptovaliutos adresas (%S) buvo nukopijuotas iš nesaugios svetainės. Jis galėjo būti modifikuotas.
+cryptoSafetyPrompt.whatCanHeading=Ką galite dėl to padaryti?
+cryptoSafetyPrompt.whatCanBody=Galite pabandyti iš naujo prisijungti naudodami naują grandinę, kad užmegztumėte saugų ryšį, arba prisiimti riziką ir atmesti šį įspėjimą.
cryptoSafetyPrompt.learnMore=Sužinoti daugiau
-cryptoSafetyPrompt.primaryAction=Reload Tab with a New Circuit
+cryptoSafetyPrompt.primaryAction=Iš naujo įkelkite skirtuką naudodami naują grandinę
cryptoSafetyPrompt.primaryActionAccessKey=R
-cryptoSafetyPrompt.secondaryAction=Dismiss Warning
+cryptoSafetyPrompt.secondaryAction=Atmesti įspėjimą
cryptoSafetyPrompt.secondaryActionAccessKey=Naudotojas B
diff --git a/chrome/locale/mk/aboutTor.dtd b/chrome/locale/mk/aboutTor.dtd
index aee03654..785c23f3 100644
--- a/chrome/locale/mk/aboutTor.dtd
+++ b/chrome/locale/mk/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "РАЦЕТЕ\nПОНАСТРАНА\nОД\nМОИТЕ\nПОДАТОЦИ">
<!ENTITY aboutTor.yec.motto "Приватноста е човеково право">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Your donation will be matched by Friends of Tor, up to $150,000.">
+<!ENTITY aboutTor.yec.donationMatch "Вашата донација ќе биде дуплицирана од Пријателите на Tor, до $150,000.">
diff --git a/chrome/locale/mk/torbutton.dtd b/chrome/locale/mk/torbutton.dtd
index 82fd4629..4cf38a72 100644
--- a/chrome/locale/mk/torbutton.dtd
+++ b/chrome/locale/mk/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Вашите прилагодени својства на прелистувачот резултираа со невообичаени безбедносни поставки. Од причини поврзани со безбедноста и приватноста, ви препорачуваме да ги изберете почетните безбедносни нивоа.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Врати на стандардно">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Напредни Безбедносни Поставки...">
+<!ENTITY torbutton.prefs.sec_change "Промени...">
<!ENTITY torbutton.circuit_display.title "Tor круг">
<!ENTITY torbutton.circuit_display.new_circuit "Нов круг за оваа веб страна">
diff --git a/chrome/locale/ms/torbutton.dtd b/chrome/locale/ms/torbutton.dtd
index 507b4c4f..2c475162 100644
--- a/chrome/locale/ms/torbutton.dtd
+++ b/chrome/locale/ms/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Keutamaan pelayar suai anda telah menyebabkan tetapan keselamatan luar jangkaan. Atas sebab keselamatan dan kerahsiaan, kami sarankan anda memilih salah satu daripada tahap keselamatan lalai yang ada.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Pulih Lalai">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Tetapan Keselamatan Lanjutan...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Litar Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Lihat baharu untuk Laman ini">
diff --git a/chrome/locale/my/torbutton.dtd b/chrome/locale/my/torbutton.dtd
index e13de6e9..6c76fca0 100644
--- a/chrome/locale/my/torbutton.dtd
+++ b/chrome/locale/my/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "သင် စိတ်ကြိုက်ရွေးထားသော ဘရောင်ဇာ၏ ချိန်ညှိမှုများသည် ပုံမှန်မဟုတ်သော လုံခြုံရေး အပြင်အဆင်များ ဖြစ်ပေါ်စေခဲ့ပါသည်။ လုံခြုံရေးနှင့် ပုဂ္ဂိုလ်လုံခြုံရေး အကြောင်းပြချက်များအတွက် မူလလုံခြုံရေးအဆင့်သို့ ရွေးထားရန် ကျွန်ုပ်တို့မှ အကြံပြုပါသည်။">
<!ENTITY torbutton.prefs.sec_restore_defaults " မူလအတိုင်း ပြန်ထားရန်">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "အဆင့်မြင့် လုံခြုံရေး အပြင်အဆင်များ...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor လမ်းကြောင်း">
<!ENTITY torbutton.circuit_display.new_circuit "ဤဆိုဒ်အတွက် လမ်းကြောင်းအသစ်">
diff --git a/chrome/locale/nb-NO/torbutton.dtd b/chrome/locale/nb-NO/torbutton.dtd
index 04ca01f8..ae488f89 100644
--- a/chrome/locale/nb-NO/torbutton.dtd
+++ b/chrome/locale/nb-NO/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Dine nettleserinnstillinger har ført med seg uvanlige sikkerhetsvalg. Av sikkerhet- og personverns-hensyn anbefaler vi at du velger en av de forvalgte sikkerhetsnivåene.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Gjenopprett forvalg">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Avanserte sikkerhetsinnstillinger...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor-krets">
<!ENTITY torbutton.circuit_display.new_circuit "Ny krets for denne siden">
diff --git a/chrome/locale/nb-NO/torbutton.properties b/chrome/locale/nb-NO/torbutton.properties
index cbd35761..2a7550ff 100644
--- a/chrome/locale/nb-NO/torbutton.properties
+++ b/chrome/locale/nb-NO/torbutton.properties
@@ -91,7 +91,7 @@ onionServices.clientAuthMissing.header=Onionsite Requires Authentication
onionServices.clientAuthMissing=Access to the onionsite requires a key but none was provided.
onionServices.clientAuthMissing.longDescription=Details: %S — The client downloaded the requested onion service descriptor but was unable to decrypt its content because client authorization information is missing.
# Tor SOCKS error 0xF5:
-onionServices.clientAuthIncorrect.pageTitle=Authorization Failed
+onionServices.clientAuthIncorrect.pageTitle=Autorisasjon Feilet
onionServices.clientAuthIncorrect.header=Onionsite Authentication Failed
onionServices.clientAuthIncorrect=The provided key is incorrect or has been revoked. Contact the onionsite administrator.
onionServices.clientAuthIncorrect.longDescription=Details: %S — The client was able to download the requested onion service descriptor but was unable to decrypt its content using the provided client authorization information. This may mean that access has been revoked.
@@ -128,7 +128,7 @@ onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
-onionServices.v2Deprecated.tryAgain=Got it
+onionServices.v2Deprecated.tryAgain=Skjønner
onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
# Onion-Location strings.
diff --git a/chrome/locale/nl/torbutton.dtd b/chrome/locale/nl/torbutton.dtd
index 4ee769ed..a88122f1 100644
--- a/chrome/locale/nl/torbutton.dtd
+++ b/chrome/locale/nl/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Uw aangepaste browservoorkeuren hebben tot ongebruikelijke beveiligingsinstellingen geleid. Uit veiligheids- en privacyoverwegingen raden we aan een van de standaard beveiligingsniveaus te kiezen.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Standaardwaarden herstellen">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Geavanceerde beveiligingsinstellingen…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor-circuit">
<!ENTITY torbutton.circuit_display.new_circuit "Nieuw circuit voor deze website">
diff --git a/chrome/locale/nl/torbutton.properties b/chrome/locale/nl/torbutton.properties
index 14f8ee0f..951140c0 100644
--- a/chrome/locale/nl/torbutton.properties
+++ b/chrome/locale/nl/torbutton.properties
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=Verwijderen
onionServices.authPreferences.removeAll=Alle verwijderen
onionServices.authPreferences.failedToGetKeys=Kan geen sleutels van tor ophalen
onionServices.authPreferences.failedToRemoveKey=Kan sleutel niet verwijderen
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
+onionServices.v2Deprecated.pageTitle=V2 Onion Site Afschrapping Waarschuwing
+onionServices.v2Deprecated.header=Versie 2 Onion Sites zal binnenkort worden afgeschaft
+onionServices.v2Deprecated=Deze onion-site zal binnenkort niet meer bereikbaar zijn. Neem contact op met de beheerder van de site en moedig hem aan te upgraden.
+onionServices.v2Deprecated.longDescription=Tor beëindigt zijn ondersteuning voor versie 2 onion diensten vanaf juli 2021, en deze onion site zal niet langer bereikbaar zijn op dit adres. Als u de beheerder van de site bent, upgrade dan spoedig naar een versie 3 onion dienst.
onionServices.v2Deprecated.tryAgain=Begrepen
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.tooltip=Deze ui-site zal binnenkort niet meer bereikbaar zijn
# Onion-Location strings.
onionLocation.alwaysPrioritize=Onions altijd prioriteit geven
diff --git a/chrome/locale/pl/aboutTor.dtd b/chrome/locale/pl/aboutTor.dtd
index af33f2e0..6750b260 100644
--- a/chrome/locale/pl/aboutTor.dtd
+++ b/chrome/locale/pl/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "RĘCE\nPRECZ\nOD\nMOICH\nDANYCH">
<!ENTITY aboutTor.yec.motto "Prawo do prywatności jest prawem człowieka. ">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/pl/torbutton.dtd b/chrome/locale/pl/torbutton.dtd
index 80c339f5..183b89a6 100644
--- a/chrome/locale/pl/torbutton.dtd
+++ b/chrome/locale/pl/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Niestandardowe preferencje przeglądarki spowodowały nietypowe ustawienia zabezpieczeń. Ze względów bezpieczeństwa i prywatności zalecamy wybranie jednego z domyślnych poziomów zabezpieczeń.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Przywróć domyślne">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Zaawansowane ustawienia zabezpieczeń…">
+<!ENTITY torbutton.prefs.sec_change "Zmień…">
<!ENTITY torbutton.circuit_display.title "Obwód Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Nowy obwód dla tej strony">
diff --git a/chrome/locale/pt-BR/aboutTor.dtd b/chrome/locale/pt-BR/aboutTor.dtd
index 0da300b7..71aa2346 100644
--- a/chrome/locale/pt-BR/aboutTor.dtd
+++ b/chrome/locale/pt-BR/aboutTor.dtd
@@ -48,7 +48,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "TIREM AS\nMÃOS\nDOS MEUS\nDADOS">
<!ENTITY aboutTor.yec.motto "Privacidade é um direito humano.">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/pt-BR/torbutton.dtd b/chrome/locale/pt-BR/torbutton.dtd
index ce1ca0b2..cfa050e8 100644
--- a/chrome/locale/pt-BR/torbutton.dtd
+++ b/chrome/locale/pt-BR/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "As configurações personalizadas do seu navegador ficaram fora do comum. Por razões de segurança e de privacidade, recomendamos que você escolha um dos níveis padrões de segurança. ">
<!ENTITY torbutton.prefs.sec_restore_defaults "Restaurar Padrões">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Configurações Avançadas de Segurança">
+<!ENTITY torbutton.prefs.sec_change "Alterar...">
<!ENTITY torbutton.circuit_display.title "Circuito Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Novo circuito para este site">
diff --git a/chrome/locale/ro/aboutTor.dtd b/chrome/locale/ro/aboutTor.dtd
index fabbdbc3..9c5d3c33 100644
--- a/chrome/locale/ro/aboutTor.dtd
+++ b/chrome/locale/ro/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "IA-ȚI\nMÂINILE\nDE PE DATELE\nMELE">
<!ENTITY aboutTor.yec.motto "Confidențialitatea este un drept uman">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/ro/torbutton.dtd b/chrome/locale/ro/torbutton.dtd
index 995d2167..d75d597e 100644
--- a/chrome/locale/ro/torbutton.dtd
+++ b/chrome/locale/ro/torbutton.dtd
@@ -46,6 +46,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Preferințele dvs. de browser personalizate au avut ca rezultat setări de securitate neobișnuite. Din motive de securitate și confidențialitate, vă recomandăm să alegeți una dintre nivelurile de securitate implicite.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Revenire la Setările Inițiale">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Setări Avansate de Securitate...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Circuit Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Circuit nou pentru acest site">
diff --git a/chrome/locale/ro/torbutton.properties b/chrome/locale/ro/torbutton.properties
index a62ad70f..494176bb 100644
--- a/chrome/locale/ro/torbutton.properties
+++ b/chrome/locale/ro/torbutton.properties
@@ -22,7 +22,7 @@ torbutton.popup.dontask = Descarcă fişiere automat de acum înainte
torbutton.popup.no_newnym = Torbutton nu îți poate oferi o identitate nouă, deoarece nu are acces la Tor Control Port.\n\nEști sigur că rulează Tor Browser Bundle?
torbutton.security_settings.menu.title = Setări de Securitate
torbutton.title.prompt_torbrowser = Informații importante Torbutton
-torbutton.popup.prompt_torbrowser = Torbutton funcționează acum în mod diferit: nu mai poate fi închis.\n\nAm făcut această schimbare deoarece Torbutton nu poate fi folosit în siguranță într-un browser care e utilizat și pentru navigare non-Tor. Erau prea multe buguri pe care nu le puteam remedia în alt fel.\n\nDacă doriți să continuați să folosiți Firefox normal, ar trebui să dezinstalați Torbutton și să descărcați Tor Browser Bundle. Proprietățile de navigare privată ale Tor Browser sunt deasemenea superioare celor ale Firefox normal, chiar și atunci când Firefox este folosit cu Torbutton.\n\nPentru a elimina Torbutton, accesați Unelte->Suplimente->Extensii și faceți click pe butonul Elimină / Remove de lângă Torbutton.
+torbutton.popup.prompt_torbrowser = Torbutton funcționează acum în mod diferit: nu mai poate fi închis.\n\nAm făcut această schimbare deoarece Torbutton nu poate fi folosit în siguranță într-un browser care e utilizat și pentru navigare non-Tor. Erau prea multe buguri pe care nu le puteam remedia în alt fel.\n\nDacă doriți să continuați să folosiți Firefox normal, ar trebui să dezinstalați Torbutton și descărcați pachetul Tor Browser. Proprietățile de navigare privată ale Tor Browser sunt deasemenea superioare celor ale Firefox normal, chiar și atunci când Firefox este folosit cu Torbutton.\n\nPentru a elimina Torbutton, accesați Unelte->Suplimente->Extensii și faceți click pe butonul Elimină / Remove de lângă Torbutton.
torbutton.popup.short_torbrowser = Informație Torbutton importantă!\n\nTorbutton este acum permanent activat.\n\nFaceți click pe Torbutton pentru mai multe informații.
torbutton.popup.confirm_plugins = Plugin-urile cum ar fi "Flash" îți pot afecta intimitatea și anonimitatea.\n\nDeasemenea ele pot ocoli Tor și îți pot dezvălui locația curentă și adresa IP.\n\nSigur doriți să activați plugin-urile?\n\n
@@ -124,12 +124,12 @@ onionServices.authPreferences.remove=Eliminare
onionServices.authPreferences.removeAll=Șterge tot
onionServices.authPreferences.failedToGetKeys=Imposibil de a prelua chei de la tor
onionServices.authPreferences.failedToRemoveKey=Nu se poate elimina cheia
-onionServices.v2Deprecated.pageTitle=V2 Onion Site Deprecation Warning
-onionServices.v2Deprecated.header=Version 2 Onion Sites will be deprecated soon
-onionServices.v2Deprecated=This onion site will not be reachable soon. Please contact the site administrator and encourage them to upgrade.
-onionServices.v2Deprecated.longDescription=Tor is ending its support for version 2 onion services beginning in July 2021, and this onion site will no longer be reachable at this address. If you are the site administrator, upgrade to a version 3 onion service soon.
+onionServices.v2Deprecated.pageTitle=Avertisment privind deprecierea site-ului Tor V2
+onionServices.v2Deprecated.header= Versiunea a 2 a a site-urilor Onion va fi învechită în curând
+onionServices.v2Deprecated=Acest site nu va putea fi accesat în curând. Contactați administratorul site-ului și rugați-l să facă upgrade.
+onionServices.v2Deprecated.longDescription=Tor va sfârsi suportul pentru versiunea a 2 a a Serviciilor Onion începand de Iulie 2021, și acest site nu va fi disponibil la această adresă. Dacă tu esti administratorul site-ului, upgradați la versiunea a 3 a a Serviciilor Onion în curand.
onionServices.v2Deprecated.tryAgain=Am înțeles
-onionServices.v2Deprecated.tooltip=This onion site will not be reachable soon
+onionServices.v2Deprecated.tooltip=Acest site Onion nu va mai fi valabil cât de curând
# Onion-Location strings.
onionLocation.alwaysPrioritize=Întotdeauna prioritate pentru serviciile Onion
@@ -146,11 +146,11 @@ onionLocation.prioritizeOnionsDescription=Prioritizați site-urile .onion când
onionLocation.onionServicesTitle=Servicii Onion
# LOCALIZATION NOTE: %S will be replaced with the cryptocurrency address.
-cryptoSafetyPrompt.cryptoWarning=A cryptocurrency address (%S) has been copied from an insecure website. It could have been modified.
-cryptoSafetyPrompt.whatCanHeading=What can you do about it?
-cryptoSafetyPrompt.whatCanBody=You can try reconnecting with a new circuit to establish a secure connection, or accept the risk and dismiss this warning.
+cryptoSafetyPrompt.cryptoWarning=O adresă de criptomonede (%S) a fost copiat de pe un site nesecurizat. Este posibil ca această adresă să fi fost modificată.
+cryptoSafetyPrompt.whatCanHeading=Ce ai putea face în această privintă?
+cryptoSafetyPrompt.whatCanBody=Puteți încerca să vă reconectați cu un circuit nou pentru a stabili o conexiune securizată, ori vă asumați riscul și refuzați avertismentul.
cryptoSafetyPrompt.learnMore=Află mai mult
-cryptoSafetyPrompt.primaryAction=Reload Tab with a New Circuit
+cryptoSafetyPrompt.primaryAction=Reîncărcați Fila cu un Circuit Nou
cryptoSafetyPrompt.primaryActionAccessKey=R
-cryptoSafetyPrompt.secondaryAction=Dismiss Warning
+cryptoSafetyPrompt.secondaryAction=Refuzați avertismentul
cryptoSafetyPrompt.secondaryActionAccessKey=B
diff --git a/chrome/locale/ru/aboutTor.dtd b/chrome/locale/ru/aboutTor.dtd
index 72d3cbb8..7ea0b5f8 100644
--- a/chrome/locale/ru/aboutTor.dtd
+++ b/chrome/locale/ru/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "РУКИ\nПРОЧЬ\nОТ МОИХ\nДАННЫХ">
<!ENTITY aboutTor.yec.motto "Приватность – право человека">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/ru/torbutton.dtd b/chrome/locale/ru/torbutton.dtd
index b5e4c379..413507e8 100644
--- a/chrome/locale/ru/torbutton.dtd
+++ b/chrome/locale/ru/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Необычная комбинация настроек браузера. По соображениям безопасности и приватности рекомендуем выбрать один из уровней безопасности по умолчанию.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Восстановить значения по умолчанию">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Дополнительные настройки безопасности...">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Цепочка Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Новая цепочка для этого сайта">
diff --git a/chrome/locale/sv-SE/aboutDialog.dtd b/chrome/locale/sv-SE/aboutDialog.dtd
index 9a2c95c5..5fd7b0bc 100644
--- a/chrome/locale/sv-SE/aboutDialog.dtd
+++ b/chrome/locale/sv-SE/aboutDialog.dtd
@@ -16,4 +16,4 @@
<!ENTITY bottomLinks.grow "Hjälp Tor-nätverket växa!">
<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license -->
<!ENTITY bottomLinks.license "Licensinformation">
-<!ENTITY tor.TrademarkStatement "'Tor' och 'Onion-logotypen' är registerade varumärken av Tor Project, Inc.">
+<!ENTITY tor.TrademarkStatement "'Tor' och 'Onion Logo' är registrerade varumärken av Tor Project, Inc.">
diff --git a/chrome/locale/sv-SE/aboutTor.dtd b/chrome/locale/sv-SE/aboutTor.dtd
index edff847d..f5e56647 100644
--- a/chrome/locale/sv-SE/aboutTor.dtd
+++ b/chrome/locale/sv-SE/aboutTor.dtd
@@ -22,7 +22,7 @@
<!ENTITY aboutTor.torbrowser_user_manual.accesskey "M">
<!ENTITY aboutTor.torbrowser_user_manual.label "Bruksanvisning för Tor Browser">
-<!ENTITY aboutTor.tor_mission.label "Tor-projektet är en amerikansk 501(c)(3) ideell organisation som främjar mänskliga rättigheter och friheter genom att skapa och distribuera anonymitets- och integritetsteknik med fri och öppen källkod, stöda deras obegränsade tillgänglighet och användning och främja deras vetenskapliga och populära förståelse.">
+<!ENTITY aboutTor.tor_mission.label "The Tor Project är en amerikansk 501(c)(3) ideell organisation som främjar mänskliga rättigheter och friheter genom att skapa och distribuera anonymitets- och integritetsteknik med fri och öppen källkod, stöda deras obegränsade tillgänglighet och användning och främja deras vetenskapliga och populära förståelse.">
<!ENTITY aboutTor.getInvolved.label "Engagera dig »">
<!ENTITY aboutTor.newsletter.tagline "Få de senaste nyheterna från Tor direkt i din inkorg.">
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "HÄNDERNA\nBORT FRÅN\nMINA\nDATA">
<!ENTITY aboutTor.yec.motto "Integritet är en mänsklig rättighet">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Din donation kommer att matchas av Friends of Tor, upp till $ 150 000.">
+<!ENTITY aboutTor.yec.donationMatch "Din donation kommer att matchas av Friends of Tor, upp till $150 000.">
diff --git a/chrome/locale/sv-SE/brand.dtd b/chrome/locale/sv-SE/brand.dtd
index de5e4f15..5617d44d 100644
--- a/chrome/locale/sv-SE/brand.dtd
+++ b/chrome/locale/sv-SE/brand.dtd
@@ -5,8 +5,8 @@
<!ENTITY brandShorterName "Tor Browser">
<!ENTITY brandShortName "Tor Browser">
<!ENTITY brandFullName "Tor Browser">
-<!ENTITY vendorShortName "Tor-projektet">
-<!ENTITY trademarkInfo.part1 "'Tor' och 'Onion-logotypen' är registerade varumärken av Tor Project, Inc.">
+<!ENTITY vendorShortName "Tor Project">
+<!ENTITY trademarkInfo.part1 "'Tor' och 'Onion Logo' är registrerade varumärken av Tor Project, Inc.">
<!-- LOCALIZATION NOTE (brandProductName):
This brand name can be used in messages where the product name needs to
remain unchanged across different versions (Nightly, Beta, etc.). -->
diff --git a/chrome/locale/sv-SE/brand.properties b/chrome/locale/sv-SE/brand.properties
index 35e97d24..e6f2ebcf 100644
--- a/chrome/locale/sv-SE/brand.properties
+++ b/chrome/locale/sv-SE/brand.properties
@@ -9,7 +9,7 @@ brandFullName=Tor Browser
# This brand name can be used in messages where the product name needs to
# remain unchanged across different versions (Nightly, Beta, etc.).
brandProductName=Tor Browser
-vendorShortName=Tor-projektet
+vendorShortName=Tor Project
homePageSingleStartMain=Firefox Start, en snabb webbplats med inbyggd sökfunktion
homePageImport=Importera din startsida från %S
diff --git a/chrome/locale/sv-SE/branding/brand.ftl b/chrome/locale/sv-SE/branding/brand.ftl
index 56cdff04..09bb00f7 100644
--- a/chrome/locale/sv-SE/branding/brand.ftl
+++ b/chrome/locale/sv-SE/branding/brand.ftl
@@ -8,5 +8,5 @@
# This brand name can be used in messages where the product name needs to
# remain unchanged across different versions (Nightly, Beta, etc.).
-brand-product-name = Tor Browser
--vendor-short-name = Tor-projektet
-trademarkInfo = 'Tor' och 'Onion-logotypen' är registerade varumärken av Tor Project, Inc.
+-vendor-short-name = Tor Project
+trademarkInfo = 'Tor' och 'Onion Logo' är registrerade varumärken av Tor Project, Inc.
diff --git a/chrome/locale/sv-SE/torbutton.dtd b/chrome/locale/sv-SE/torbutton.dtd
index ee739e20..627a9fc4 100644
--- a/chrome/locale/sv-SE/torbutton.dtd
+++ b/chrome/locale/sv-SE/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Dina anpassade webbläsarinställningar har resulterat i ovanliga säkerhetsinställningar. Av säkerhets- och integritetsskäl rekommenderar vi att du använder en av de fördefinierade säkerhetsnivåerna.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Återställ standardvärden">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Avancerade säkerhetsinställningar…">
+<!ENTITY torbutton.prefs.sec_change "Ändra…">
<!ENTITY torbutton.circuit_display.title "Tor-krets">
<!ENTITY torbutton.circuit_display.new_circuit "Ny krets för denna webbplats">
diff --git a/chrome/locale/sv-SE/torbutton.properties b/chrome/locale/sv-SE/torbutton.properties
index e8445c5e..1b23b6fe 100644
--- a/chrome/locale/sv-SE/torbutton.properties
+++ b/chrome/locale/sv-SE/torbutton.properties
@@ -22,7 +22,7 @@ torbutton.popup.dontask = Hämta filer automatiskt i fortsättningen
torbutton.popup.no_newnym = Torbutton kan inte säkert ge dig en ny identitet. Det har inte tillgång till Tor Control Port.\n\nKör du Tor Browser Bundle?
torbutton.security_settings.menu.title = Säkerhetsinställningar
torbutton.title.prompt_torbrowser = Viktig information om Torbutton
-torbutton.popup.prompt_torbrowser = Torbutton fungerar annorlunda nu: Du kan inte slå av den längre.\n\nVi gjorde denna förändring eftersom det inte är säkert att använda Torbutton i en webbläsare som också används för icke-Tor surfning. Det var för många fel som vi inte kunde åtgärda på något annat sätt.\n\nOm du vill fortsätta använda Firefox normalt så bör du avinstallera Tor Browser och hämta Tor Browser Bundle. Tor Browser skyddar din integritet bättre än vanliga Firefox, även när Firefox används med Tor Button.\n\nFör att ta bort Torbutton, gå till Verktyg->Tillägg->Tillägg och klicka på Ta bort-knappen bredvid Torbutton.
+torbutton.popup.prompt_torbrowser = Torbutton fungerar annorlunda nu: du kan inte stänga av den längre.\n\nVi gjorde denna förändring eftersom det inte är säkert att använda Torbutton i en webbläsare som också används för surfning utan Tor. Det fanns för många fel som vi inte kunde åtgärda på något annat sätt.\n\nOm du vill fortsätta använda Firefox normalt bör du avinstallera Torbotton och hämta Tor Browser Bundle. Tor Browser skyddar din integritet bättre än vanliga Firefox, även när Firefox används med Torbutton.\n\nFör att ta bort Torbutton, gå till Verktyg->Tillägg->Tillägg och klicka på knappen Ta bort bredvid Torbutton.
torbutton.popup.short_torbrowser = Viktig information om Torbutton!\n\nTorbutton är nu alltid aktiverad.\n\nKlicka på Torbutton för mer information.
torbutton.popup.confirm_plugins = Insticksmoduler så som Flash kan äventyra din anonymitet och personliga integritet.\n\nDe kan också kringgå Tor för att avslöja var du befinner dig och vad din IP-adress är.\n\nÄr du säker på att du vill aktivera insticksmoduler?\n\n
@@ -33,7 +33,7 @@ torbutton.maximize_warning = Maximering av Tor Browser kan ge webbplatser möjli
# Canvas permission prompt. Strings are kept here for ease of translation.
canvas.siteprompt=Denna webbplats (%S) försökte extrahera HTML5-kanvasbilddata, som skulle kunna användas för att identifiera just din dator.\n\nSka Tor Browser tillåta denna webbplats att extrahera HTML5-kanvasbilddata?
-canvas.notNow=Inte just nu
+canvas.notNow=Inte nu
canvas.notNowAccessKey=N
canvas.allow=Tillåt i framtiden
canvas.allowAccessKey=A
@@ -89,12 +89,12 @@ onionServices.rendezvousFailed.longDescription=Detaljer: %S — Klienten misslyc
onionServices.clientAuthMissing.pageTitle=Autentisering krävs
onionServices.clientAuthMissing.header=Onion-webbplats kräver autentisering
onionServices.clientAuthMissing=Tillgång till onion-webbplats kräver en nyckel men ingen tillhandahölls.
-onionServices.clientAuthMissing.longDescription=Detaljer: %S — Klienten hämtade den begärda beskrivningen för onion-tjänsten men kunde inte dekryptera dess innehåll eftersom information om klientautentisering saknas.
+onionServices.clientAuthMissing.longDescription=Detaljer: %S — Klienten hämtade den begärda beskrivningen för onion-tjänsten men kunde inte dekryptera dess innehåll eftersom klientauktoriseringsinformation saknas.
# Tor SOCKS error 0xF5:
onionServices.clientAuthIncorrect.pageTitle=Autentisering misslyckades
onionServices.clientAuthIncorrect.header=Autentisering av onion-webbplatsen misslyckades
onionServices.clientAuthIncorrect=Den medföljande nyckeln är felaktig eller har återkallats. Kontakta administratör för onion-webbplats.
-onionServices.clientAuthIncorrect.longDescription=Detaljer: %S — Klienten kunde hämta den begärda beskrivningen för onion-tjänsten men kunde inte dekryptera dess innehåll med den tillhandahållna klientauktoriseringsinformationen. Detta kan innebära att åtkomst har återkallats.
+onionServices.clientAuthIncorrect.longDescription=Detaljer: %S — Klienten kunde hämta den begärda beskrivningen för onion-tjänsten men kunde inte dekryptera dess innehåll med den tillhandahållna klientauktoriseringsinformationen. Det kan innebära att åtkomsten har återkallats.
# Tor SOCKS error 0xF6:
onionServices.badAddress.pageTitle=Problem med att läsa in onion-webbplats
onionServices.badAddress.header=Ogiltig onion-webbplatsadress
diff --git a/chrome/locale/th/browserOnboarding.properties b/chrome/locale/th/browserOnboarding.properties
index ef2158e1..25170a00 100644
--- a/chrome/locale/th/browserOnboarding.properties
+++ b/chrome/locale/th/browserOnboarding.properties
@@ -52,7 +52,7 @@ onboarding.tour-tor-toolbar=แถบเครื่องมือ
onboarding.tour-tor-toolbar-update-9.0.title=ลาก่อน Onion Button
onboarding.tour-tor-toolbar-update-9.0.description=เราอยากให้ประสบการณ์ของคุณในการใช้ Tor ผสมผสานเข้ากับ Tor Browser ได้อย่างสมบูรณ์
onboarding.tour-tor-toolbar-update-9.0.description-para2=That's why now, rather than using the onion button, you can see your Tor Circuit via the [i] in the URL bar and request a New Identity using the toolbar button or the [≡] menu.
-onboarding.tour-tor-toolbar-update-9.0.button=How to Request a New Identity
+onboarding.tour-tor-toolbar-update-9.0.button=วิธีการขอตัวตนใหม่
onboarding.tour-tor-toolbar-update-9.0.next-button=ไปที่เครือข่าย Tor
# Circuit Display onboarding.
diff --git a/chrome/locale/th/torbutton.dtd b/chrome/locale/th/torbutton.dtd
index 88593dce..ce079acd 100644
--- a/chrome/locale/th/torbutton.dtd
+++ b/chrome/locale/th/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "การตั้งค่าเบราว์เซอร์ที่กำหนดเองของคุณส่งผลให้เกิดการตั้งค่าที่ไม่ความปลอดภัย เพื่อเหตุผลด้านความปลอดภัยและความเป็นส่วนตัวเรา ขอแนะนำให้คุณเลือกหนึ่งในระดับความปลอดภัยค่าเริ่มต้น">
<!ENTITY torbutton.prefs.sec_restore_defaults "กลับสู่ค่ามาตรฐาน">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "การตั้งค่าความปลอดภัยชั้นสูง">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "การเชื่องโยง Tor ">
<!ENTITY torbutton.circuit_display.new_circuit "แหล่งเชื่อมโยงข้อมูลใหม่สำหรับเว็บไซต์นี้">
diff --git a/chrome/locale/tr/aboutTBUpdate.dtd b/chrome/locale/tr/aboutTBUpdate.dtd
index 38d6fc77..d003ba19 100644
--- a/chrome/locale/tr/aboutTBUpdate.dtd
+++ b/chrome/locale/tr/aboutTBUpdate.dtd
@@ -1,7 +1,7 @@
<!ENTITY aboutTBUpdate.changelogTitle "Tor Browser değişiklik günlüğü">
<!ENTITY aboutTBUpdate.updated "Tor Browser güncellendi.">
-<!ENTITY aboutTBUpdate.linkPrefix "Bu sürüm hakkındaki güncel bilgiler ">
-<!ENTITY aboutTBUpdate.linkLabel "web sitemizden edinilebilir">
+<!ENTITY aboutTBUpdate.linkPrefix "Bu sürüm hakkındaki güncel bilgileri ">
+<!ENTITY aboutTBUpdate.linkLabel "web sitemizden alabilirsiniz">
<!ENTITY aboutTBUpdate.linkSuffix ".">
<!ENTITY aboutTBUpdate.version "Sürüm">
<!ENTITY aboutTBUpdate.releaseDate "Yayım tarihi">
diff --git a/chrome/locale/tr/aboutTor.dtd b/chrome/locale/tr/aboutTor.dtd
index 7496155b..dc3eb89e 100644
--- a/chrome/locale/tr/aboutTor.dtd
+++ b/chrome/locale/tr/aboutTor.dtd
@@ -22,7 +22,7 @@
<!ENTITY aboutTor.torbrowser_user_manual.accesskey "M">
<!ENTITY aboutTor.torbrowser_user_manual.label "Tor Browser rehberi">
-<!ENTITY aboutTor.tor_mission.label "Tor Projesi, Birleşik Devletler 501(c)(3) vergi muafiyeti maddesi kapsamında, özgür ve açık kaynaklı anonimlik ve kişisel gizlilik teknolojileri geliştirerek insan hakları ve özgürlüklerini ileriye götürmeyi, bu teknolojilerin bilimsel ve kültürel olarak bilinirliğini arttırmayı ve herkes tarafından erişebilmesini sağlamak amacıyla çalışan, kar amacı gütmeyen bir kuruluştur.">
+<!ENTITY aboutTor.tor_mission.label "Tor Projesi, Birleşik Devletler 501(c)(3) vergi muafiyeti maddesi kapsamında, özgür ve açık kaynaklı anonimlik ve kişisel gizlilik teknolojileri geliştirerek insan hakları ve özgürlüklerini ileriye götürmek, bu teknolojilerin bilimsel ve kültürel olarak bilinirliğini arttırmak ve herkes tarafından erişebilmesini sağlamak amacıyla çalışan, kar amacı gütmeyen bir kuruluştur.">
<!ENTITY aboutTor.getInvolved.label "Katkıda bulunun »">
<!ENTITY aboutTor.newsletter.tagline "Tor gelişmeleri ile ilgili e-posta almak ister misiniz?">
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "VERİLERİME\nDOKUNMA">
<!ENTITY aboutTor.yec.motto "Kişisel gizlilik bir insan hakkıdır">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Friends of Tor, $150.000 tutarını aşmayan bağışlarınız kadar katkıda bulunacak.">
+<!ENTITY aboutTor.yec.donationMatch "Friends of Tor, $150.000 altında yaptığınız bağış kadar katkıda bulunacak.">
diff --git a/chrome/locale/tr/torbutton.dtd b/chrome/locale/tr/torbutton.dtd
index 76ec624e..d72a1242 100644
--- a/chrome/locale/tr/torbutton.dtd
+++ b/chrome/locale/tr/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Tarayıcınız standart olmayan özel güvenlik düzeyi ayarları kullanıyor. Güvenlik ve gizliliğinizi korumak için aşağıdaki varsayılan güvenlik ayarı düzeylerinden birini seçmeniz önerilir.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Varsayılanları yükle">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Gelişmiş güvenlik düzeyi ayarları…">
+<!ENTITY torbutton.prefs.sec_change "Değiştir…">
<!ENTITY torbutton.circuit_display.title "Tor devresi">
<!ENTITY torbutton.circuit_display.new_circuit "Bu sitenin devresini yenile">
diff --git a/chrome/locale/vi/torbutton.dtd b/chrome/locale/vi/torbutton.dtd
index 929319b4..2b218719 100644
--- a/chrome/locale/vi/torbutton.dtd
+++ b/chrome/locale/vi/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "Những điều chỉnh trong trình duyệt của bạn vừa tạo ra những lỗi bảo mật bất thường. Vì những lý do bảo mật và riêng tư, chúng tôi khuyến cáo bạn chọn những cấp độ bảo mật mặc định khác.">
<!ENTITY torbutton.prefs.sec_restore_defaults "Khôi phục trạng thái mặc định">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "Advanced Security Settings…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Mạch Tor">
<!ENTITY torbutton.circuit_display.new_circuit "Mạch Tor mới cho trang này">
diff --git a/chrome/locale/zh-CN/aboutTor.dtd b/chrome/locale/zh-CN/aboutTor.dtd
index ed51009f..4aa0815c 100644
--- a/chrome/locale/zh-CN/aboutTor.dtd
+++ b/chrome/locale/zh-CN/aboutTor.dtd
@@ -47,7 +47,7 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.slogan "HANDS\nOFF\nMY\nDATA">
+<!ENTITY aboutTor.yec.slogan "别碰\n我的\n隐私">
<!ENTITY aboutTor.yec.motto "隐私是一项人权">
<!-- LOCALIZATION NOTE (aboutTor.yec.donationMatch): Please translate the 'Friends of Tor' phrase, but
also format it like the name of an organization in whichever way that is appropriate for your locale.
diff --git a/chrome/locale/zh-CN/torbutton.dtd b/chrome/locale/zh-CN/torbutton.dtd
index 919e457c..d789c08f 100644
--- a/chrome/locale/zh-CN/torbutton.dtd
+++ b/chrome/locale/zh-CN/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "您自定义的浏览器设置导致了不安全的安全设置。出于安全和隐私考虑,我们建议您选择一个默认的安全级别。">
<!ENTITY torbutton.prefs.sec_restore_defaults "恢复默认设置">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "高级安全选项…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor 链路">
<!ENTITY torbutton.circuit_display.new_circuit "为此站点使用新线路">
diff --git a/chrome/locale/zh-TW/aboutTor.dtd b/chrome/locale/zh-TW/aboutTor.dtd
index 494cdc50..8ec68152 100644
--- a/chrome/locale/zh-TW/aboutTor.dtd
+++ b/chrome/locale/zh-TW/aboutTor.dtd
@@ -56,4 +56,4 @@
Thank you!
-->
-<!ENTITY aboutTor.yec.donationMatch "Your donation will be matched by Friends of Tor, up to $150,000.">
+<!ENTITY aboutTor.yec.donationMatch "Friends of Tor 組織將會捐助與您所捐助的款項相同的金額,上限為$150,000。">
diff --git a/chrome/locale/zh-TW/torbutton.dtd b/chrome/locale/zh-TW/torbutton.dtd
index 64b43a0e..9af68ea9 100644
--- a/chrome/locale/zh-TW/torbutton.dtd
+++ b/chrome/locale/zh-TW/torbutton.dtd
@@ -45,6 +45,7 @@
<!ENTITY torbutton.prefs.sec_custom_summary "您的瀏覽器個人化設定可能會造成安全性的疑慮。基於個人網路安全與隱私的考量,建議您選用預設的安全性層級選項。">
<!ENTITY torbutton.prefs.sec_restore_defaults "恢復到預設值">
<!ENTITY torbutton.prefs.sec_advanced_security_settings "進階安全性設定…">
+<!ENTITY torbutton.prefs.sec_change "Change…">
<!ENTITY torbutton.circuit_display.title "Tor 迴路">
<!ENTITY torbutton.circuit_display.new_circuit "建立新的迴路來連接上此網站">
1
0
[tor-browser-build/master] Switch nightly desktop builds over to 91.4.0esr-based 11.5
by gk@torproject.org 06 Dec '21
by gk@torproject.org 06 Dec '21
06 Dec '21
commit 7f2f33e775ad34cddc6304b847a8f1cd11c0f09b
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Dec 6 11:37:16 2021 +0000
Switch nightly desktop builds over to 91.4.0esr-based 11.5
---
projects/firefox/config | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index d889fe3..49a1e36 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -8,9 +8,9 @@ git_submodule: 1
gpg_keyring: torbutton.gpg
var:
- firefox_platform_version: 91.3.0
+ firefox_platform_version: 91.4.0
firefox_version: '[% c("var/firefox_platform_version") %]esr'
- torbrowser_branch: 11.0
+ torbrowser_branch: 11.5
branding_directory: 'browser/branding/alpha'
copyright_year: '[% exec("git show -s --format=%ci").remove("-.*") %]'
deps:
1
0
commit e4bb9d3eaa5e6997d49ff30f47ac0ec052fbfc95
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Dec 6 11:32:37 2021 +0000
Fold in old Changelog entries
---
.../tor-browser/Bundle-Data/Docs/ChangeLog.txt | 86 ++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index fee227f..d1f8fdd 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,3 +1,89 @@
+Tor Browser 11.0.2 - December 7 2021
+ * Windows + OS X + Linux
+ * Update Firefox to 91.4.0esr
+ * Bug 40318: Remove check for DISPLAY env var in start-tor-browser [tor-browser-build]
+ * Bug 40386: Add new default obfs4 bridge "deusexmachina" [tor-browser-build]
+ * Bug 40682: Disable network.proxy.allow_bypass [tor-browser]
+ * Linux
+ * Bug 40387: Remove some fonts on Linux [tor-browser-build]
+
+Tor Browser 11.0.1 - November 14 2021
+ * Windows + OS X + Linux
+ * Tor Launcher 0.2.32
+ * Bug 40059: YEC activist sign empty in about:tor on RTL locales [torbutton]
+ * Bug 40383: Workaround issue in https-e wasm [tor-browser-build]
+ * Bug 40438: Add Blockchair as a search engine [tor-browser]
+ * Bug 40689: Change Blockchair Search provider's HTTP method [tor-browser]
+ * Bug 40690: Browser chrome breaks when private browsing mode is turned off [tor-browser]
+ * Bug 40700: Switch Firefox recommendations off by default [tor-browser]
+
+Tor Browser 11.0 - November 8 2021
+ * Windows + OS X + Linux
+ * Update Firefox to 91.3.0esr
+ * Update Tor to tor-0.4.6.8
+ * Bug 32624: localStorage is not shared between tabs [tor-browser]
+ * Bug 33125: Remove xpinstall.whitelist.add* as they don't do anything anymore [tor-browser]
+ * Bug 34188: Cleanup extensions.* prefs [tor-browser]
+ * Bug 40004: Convert tl-protocol to async. [tor-launcher]
+ * Bug 40012: Watch all requested tor events [tor-launcher]
+ * Bug 40027: Make torbutton_send_ctrl_cmd async [torbutton]
+ * Bug 40042: Add missing parameter of createTransport [torbutton]
+ * Bug 40043: Delete all plugin-related protections [torbutton]
+ * Bug 40045: Teach the controller about status_client [torbutton]
+ * Bug 40046: Support arbitrary watch events [torbutton]
+ * Bug 40047: New string for Security Level panel [torbutton]
+ * Bug 40048: Protonify Circuit Display Panel [torbutton]
+ * Bug 40053: investigate fingerprinting potential of extended TextMetrics interface [tor-browser]
+ * Bug 40083: Make sure Region.jsm fetching is disabled [tor-browser]
+ * Bug 40177: Clean up obsolete preferences in our 000-tor-browser.js [tor-browser]
+ * Bug 40220: Make sure tracker cookie purging is disabled [tor-browser]
+ * Bug 40342: Set `gfx.bundled-fonts.activate = 1` to preserve current bundled fonts behaviour [tor-browser]
+ * Bug 40463: Disable network.http.windows10-sso.enabled in FF 91 [tor-browser]
+ * Bug 40483: Deutsche Welle v2 redirect [tor-browser]
+ * Bug 40534: Cannot open URLs on command line with Tor Browser 10.5 [tor-browser]
+ * Bug 40547: UX: starting in offline mode can result in difficulty to connect later [tor-browser]
+ * Bug 40548: Set network.proxy.failover_direct to false in FF 91 [tor-browser]
+ * Bug 40561: Refactor about:torconnect implementation [tor-browser]
+ * Bug 40567: RFPHelper is not init until after about:torconnect bootstraps [tor-browser]
+ * Bug 40597: Implement TorSettings module [tor-browser]
+ * Bug 40600: Multiple pages as home page unreliable in 11.0a4 [tor-browser]
+ * Bug 40616: UX: multiple about:torconnect [tor-browser]
+ * Bug 40624: TorConnect banner always visible in about:preferences#tor even after bootstrap [tor-browser]
+ * Bug 40626: Update Security Level styling to match Proton UI [tor-browser]
+ * Bug 40628: Checkbox wrong color in about:torconnect in dark mode theme [tor-browser]
+ * Bug 40630: Update New Identity and New Circuit icons [tor-browser]
+ * Bug 40631: site identity icons are not being displayed properly [tor-browser]
+ * Bug 40632: Proton'ify Circuit Display Panel [tor-browser]
+ * Bug 40634: Style updates for Onion Error Pages [tor-browser]
+ * Bug 40636: Fix about:torconnect 'Connect' border radius in about:preferences#tor [tor-browser]
+ * Bug 40641: Update Security Level selection in about:preferences to match style as tracking protection option bubbles [tor-browser]
+ * Bug 40648: Replace onion pattern divs/css with tiling SVG [tor-browser]
+ * Bug 40653: Onion Available text not aligned correctly in toolbar in ESR91 [tor-browser]
+ * Bug 40655: esr91 is suggesting to make Tor Browser the default browse [tor-browser]
+ * Bug 40657: esr91 is missing "New identity" in hamburger menu [tor-browser]
+ * Bug 40680: Prepare update to localized assets for YEC [tor-browser]
+ * Bug 40686: Update Onboarding link for 11.0 [tor-browser]
+ * Build System
+ * Windows + OS X + Linux
+ * Update Go to 1.16.9
+ * Bug 40048: Remove projects/clang-source [tor-browser-build]
+ * Bug 40347: Make the list of toolchain updates needed for firefox91 [tor-browser-build]
+ * Bug 40363: Change bsaes git url [tor-browser-build]
+ * Bug 40366: Use bullseye to build https-everywhere [tor-browser-build]
+ * Bug 40368: Use system's python3 for https-everywhere [tor-browser-build]
+ * Windows + Linux
+ * Bug 40357: Update binutils to 2.35.2 [tor-browser-build]
+ * Windows
+ * Bug 28240: switch from SJLJ exception handling to Dwarf2 in mingw for win32 [tor-browser-build]
+ * Bug 40306: Update Windows toolchain to switch to mozilla91 [tor-browser-build]
+ * Bug 40376: Use python3 for running pe_checksum_fix.py [tor-browser-build]
+ * OS X
+ * Bug 40307: Update macOS toolchain to switch to mozilla91 [tor-browser-build]
+ * Linux
+ * Bug 40222: Bump GCC to 10.3.0 for Linux [tor-browser-build]
+ * Bug 40305: Update Linux toolchain to switch to mozilla91 [tor-browser-build]
+ * Bug 40353: Temporarily disable rlbox for linux builds [tor-browser-build]
+
Tor Browser 11.0a10 - November 4 2021
* Windows + OS X + Linux
* Update Firefox to 91.3.0esr
1
0
06 Dec '21
commit 1ba008a63a8ccd4bbded3de74cf9b5229404bbd6
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Dec 6 11:31:29 2021 +0000
Fix Tor Browser version in Changelog
---
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index 6cf70db..d1f8fdd 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,4 +1,4 @@
-Tor Browser 11.0.1 - December 7 2021
+Tor Browser 11.0.2 - December 7 2021
* Windows + OS X + Linux
* Update Firefox to 91.4.0esr
* Bug 40318: Remove check for DISPLAY env var in start-tor-browser [tor-browser-build]
1
0
[tor-browser-build/maint-11.0] Bug 40386: Add new default obfs4 bridge "deusexmachina"
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit 19d562958b1780d1dddca0163004152b77c25e41
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Tue Nov 30 20:18:39 2021 +0100
Bug 40386: Add new default obfs4 bridge "deusexmachina"
---
projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
index 22e9984..2fbe392 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
@@ -17,6 +17,7 @@ pref("extensions.torlauncher.default_bridge.obfs4.12", "obfs4 146.57.248.225:22
pref("extensions.torlauncher.default_bridge.obfs4.13", "obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0");
pref("extensions.torlauncher.default_bridge.obfs4.14", "obfs4 [2a0c:4d80:42:702::1]:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0");
pref("extensions.torlauncher.default_bridge.obfs4.15", "obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.16", "obfs4 185.100.85.3:443 5B403DFE34F4872EB027059CECAE30B0C864B3A2 cert=bWUdFUe8io9U6JkSLoGAvSAUDcB779/shovCYmYAQb/pW/iEAMZtO/lCd94OokOF909TPA iat-mode=2");
pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek_lite 192.0.2.2:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
1
0
[tor-browser-build/maint-11.0] Bug 40318: Remove check for DISPLAY env var in start-tor-browser
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit e22cd4e5deedb685f058f20f431b9dfc8c44fca9
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Thu Nov 11 12:56:40 2021 +0100
Bug 40318: Remove check for DISPLAY env var in start-tor-browser
When using Wayland, the DISPLAY environment variable does not need to be
set, so the start-tor-browser script should not fail in that case.
Wayland support is still disabled by default in Firefox, and users who
want to enable it will need to set the MOZ_ENABLE_WAYLAND environment
variable.
---
projects/tor-browser/RelativeLink/start-tor-browser | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/projects/tor-browser/RelativeLink/start-tor-browser b/projects/tor-browser/RelativeLink/start-tor-browser
index 624bb3c..cd70765 100755
--- a/projects/tor-browser/RelativeLink/start-tor-browser
+++ b/projects/tor-browser/RelativeLink/start-tor-browser
@@ -7,16 +7,7 @@
complain_dialog_title="Tor Browser"
-# First, make sure DISPLAY is set. If it isn't, we're hosed; scream
-# at stderr and die.
-if [ "x$DISPLAY" = "x" ]; then
- echo "$complain_dialog_title must be run within the X Window System." >&2
- echo "Exiting." >&2
- exit 1
-fi
-
-# Second, make sure this script wasn't started as 'sh start-tor-browser' or
-# similar.
+# Make sure this script wasn't started as 'sh start-tor-browser' or similar.
if [ "x$BASH" = "x" ]; then
echo "$complain_dialog_title should be started as './start-tor-browser'"
echo "Exiting." >&2
1
0
[tor-browser-build/maint-11.0] Pick up a few more fixes for 11.0.2
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit 7d9eb93e0f6bd6eaf4346e56f3b260406091fd95
Author: Matthew Finkel <sysrqb(a)torproject.org>
Date: Fri Dec 3 19:52:18 2021 +0000
Pick up a few more fixes for 11.0.2
---
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 2 ++
rbm.conf | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index ad0ed52..6cf70db 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,6 +1,8 @@
Tor Browser 11.0.1 - December 7 2021
* Windows + OS X + Linux
* Update Firefox to 91.4.0esr
+ * Bug 40318: Remove check for DISPLAY env var in start-tor-browser [tor-browser-build]
+ * Bug 40386: Add new default obfs4 bridge "deusexmachina" [tor-browser-build]
* Bug 40682: Disable network.proxy.allow_bypass [tor-browser]
* Linux
* Bug 40387: Remove some fonts on Linux [tor-browser-build]
diff --git a/rbm.conf b/rbm.conf
index 3a32f8b..b1c49f2 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -58,7 +58,7 @@ buildconf:
var:
torbrowser_version: '11.0.2'
- torbrowser_build: 'build2'
+ torbrowser_build: 'build3'
torbrowser_incremental_from:
- 11.0.1
project_name: tor-browser
1
0
[tor-browser-build/master] Merge remote-tracking branch 'boklmgl/bug_40318'
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit 3da16ab0db7ea2e6e6bed058910b679fc9373158
Merge: f80537e 63d5277
Author: Matthew Finkel <sysrqb(a)torproject.org>
Date: Fri Dec 3 19:50:05 2021 +0000
Merge remote-tracking branch 'boklmgl/bug_40318'
projects/tor-browser/RelativeLink/start-tor-browser | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
1
0
[tor-browser-build/master] Bug 40318: Remove check for DISPLAY env var in start-tor-browser
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit 63d527733e6990c9424d5976a779a9574eef5c47
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Thu Nov 11 12:56:40 2021 +0100
Bug 40318: Remove check for DISPLAY env var in start-tor-browser
When using Wayland, the DISPLAY environment variable does not need to be
set, so the start-tor-browser script should not fail in that case.
Wayland support is still disabled by default in Firefox, and users who
want to enable it will need to set the MOZ_ENABLE_WAYLAND environment
variable.
---
projects/tor-browser/RelativeLink/start-tor-browser | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/projects/tor-browser/RelativeLink/start-tor-browser b/projects/tor-browser/RelativeLink/start-tor-browser
index 624bb3c..cd70765 100755
--- a/projects/tor-browser/RelativeLink/start-tor-browser
+++ b/projects/tor-browser/RelativeLink/start-tor-browser
@@ -7,16 +7,7 @@
complain_dialog_title="Tor Browser"
-# First, make sure DISPLAY is set. If it isn't, we're hosed; scream
-# at stderr and die.
-if [ "x$DISPLAY" = "x" ]; then
- echo "$complain_dialog_title must be run within the X Window System." >&2
- echo "Exiting." >&2
- exit 1
-fi
-
-# Second, make sure this script wasn't started as 'sh start-tor-browser' or
-# similar.
+# Make sure this script wasn't started as 'sh start-tor-browser' or similar.
if [ "x$BASH" = "x" ]; then
echo "$complain_dialog_title should be started as './start-tor-browser'"
echo "Exiting." >&2
1
0
[tor-browser-build/master] Merge remote-tracking branch 'boklmgl/bug_40386'
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit f80537ea43148f9b599da377c8bba24f179ebf0d
Merge: 2a89fc9 2f83fc5
Author: Matthew Finkel <sysrqb(a)torproject.org>
Date: Fri Dec 3 19:49:37 2021 +0000
Merge remote-tracking branch 'boklmgl/bug_40386'
projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js | 1 +
1 file changed, 1 insertion(+)
1
0
[tor-browser-build/master] Bug 40386: Add new default obfs4 bridge "deusexmachina"
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit 2f83fc5fd5a4c0a4d531cedc8d4d7a068b1937ec
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Tue Nov 30 20:18:39 2021 +0100
Bug 40386: Add new default obfs4 bridge "deusexmachina"
---
projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
index 22e9984..2fbe392 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
@@ -17,6 +17,7 @@ pref("extensions.torlauncher.default_bridge.obfs4.12", "obfs4 146.57.248.225:22
pref("extensions.torlauncher.default_bridge.obfs4.13", "obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0");
pref("extensions.torlauncher.default_bridge.obfs4.14", "obfs4 [2a0c:4d80:42:702::1]:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0");
pref("extensions.torlauncher.default_bridge.obfs4.15", "obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.16", "obfs4 185.100.85.3:443 5B403DFE34F4872EB027059CECAE30B0C864B3A2 cert=bWUdFUe8io9U6JkSLoGAvSAUDcB779/shovCYmYAQb/pW/iEAMZtO/lCd94OokOF909TPA iat-mode=2");
pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek_lite 192.0.2.2:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
1
0
[tor-browser-build/maint-11.0] fixup! Release preparations for 11.0.2
by sysrqb@torproject.org 03 Dec '21
by sysrqb@torproject.org 03 Dec '21
03 Dec '21
commit d47288bb5cc9cec59bcf6108c7957373a3bce763
Author: Matthew Finkel <sysrqb(a)torproject.org>
Date: Fri Dec 3 02:02:22 2021 +0000
fixup! Release preparations for 11.0.2
---
projects/firefox/config | 2 +-
rbm.conf | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index 36f39fb..98325be 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: 'firefox-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %]'
-git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build4'
+git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build1'
tag_gpg_id: 1
git_url: https://git.torproject.org/tor-browser.git
git_submodule: 1
diff --git a/rbm.conf b/rbm.conf
index 208413e..3a32f8b 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -58,7 +58,7 @@ buildconf:
var:
torbrowser_version: '11.0.2'
- torbrowser_build: 'build1'
+ torbrowser_build: 'build2'
torbrowser_incremental_from:
- 11.0.1
project_name: tor-browser
1
0
[tor-browser-build/maint-11.0] Bug 40387: Remove some fonts on Linux
by sysrqb@torproject.org 02 Dec '21
by sysrqb@torproject.org 02 Dec '21
02 Dec '21
commit 800ba228e634b769687c31dfb51dff9866a048d9
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Tue Nov 30 20:45:22 2021 +0100
Bug 40387: Remove some fonts on Linux
Remove NotoSansGurmukhi-Regular.ttf and NotoSansSinhala-Regular.ttf
which are causing issues on some systems.
---
projects/fonts/config | 2 --
1 file changed, 2 deletions(-)
diff --git a/projects/fonts/config b/projects/fonts/config
index 9d11d2c..4e3719d 100644
--- a/projects/fonts/config
+++ b/projects/fonts/config
@@ -23,7 +23,6 @@ var:
- NotoSansEthiopic-Regular.ttf
- NotoSansGeorgian-Regular.ttf
- NotoSansGujarati-Regular.ttf
- - NotoSansGurmukhi-Regular.ttf
- NotoSansHebrew-Regular.ttf
- NotoSansKannada-Regular.ttf
- NotoSansKhmer-Regular.ttf
@@ -31,7 +30,6 @@ var:
- NotoSansMalayalam-Regular.ttf
- NotoSansMyanmar-Regular.ttf
- NotoSansOriya-Regular.ttf
- - NotoSansSinhala-Regular.ttf
- NotoSansTamil-Regular.ttf
- NotoSansTelugu-Regular.ttf
- NotoSansThaana-Regular.ttf
1
0
02 Dec '21
commit 80a73f38e6a3720ed83518e86a74d68690b277f8
Author: Matthew Finkel <sysrqb(a)torproject.org>
Date: Thu Dec 2 14:19:29 2021 +0000
Release preparations for 11.0.2
Version and Changelog updates
---
projects/firefox/config | 2 +-
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 7 +++++++
rbm.conf | 5 ++---
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index 249c2c7..36f39fb 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -8,7 +8,7 @@ git_submodule: 1
gpg_keyring: torbutton.gpg
var:
- firefox_platform_version: 91.3.0
+ firefox_platform_version: 91.4.0
firefox_version: '[% c("var/firefox_platform_version") %]esr'
torbrowser_branch: 11.0
branding_directory: 'browser/branding/alpha'
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index a542294..ad0ed52 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,3 +1,10 @@
+Tor Browser 11.0.1 - December 7 2021
+ * Windows + OS X + Linux
+ * Update Firefox to 91.4.0esr
+ * Bug 40682: Disable network.proxy.allow_bypass [tor-browser]
+ * Linux
+ * Bug 40387: Remove some fonts on Linux [tor-browser-build]
+
Tor Browser 11.0.1 - November 14 2021
* Windows + OS X + Linux
* Tor Launcher 0.2.32
diff --git a/rbm.conf b/rbm.conf
index 2ba2ac0..208413e 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -57,11 +57,10 @@ buildconf:
git_signtag_opt: '-s'
var:
- torbrowser_version: '11.0.1'
+ torbrowser_version: '11.0.2'
torbrowser_build: 'build1'
torbrowser_incremental_from:
- - 10.5.10
- - 11.0
+ - 11.0.1
project_name: tor-browser
multi_lingual: 0
build_mar: 1
1
0
[tor-browser-build/master] Bug 40387: Remove some fonts on Linux
by sysrqb@torproject.org 02 Dec '21
by sysrqb@torproject.org 02 Dec '21
02 Dec '21
commit 2a89fc9e333646eaea46823cf6fc9533e89f61bf
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Tue Nov 30 20:45:22 2021 +0100
Bug 40387: Remove some fonts on Linux
Remove NotoSansGurmukhi-Regular.ttf and NotoSansSinhala-Regular.ttf
which are causing issues on some systems.
---
projects/fonts/config | 2 --
1 file changed, 2 deletions(-)
diff --git a/projects/fonts/config b/projects/fonts/config
index 9d11d2c..4e3719d 100644
--- a/projects/fonts/config
+++ b/projects/fonts/config
@@ -23,7 +23,6 @@ var:
- NotoSansEthiopic-Regular.ttf
- NotoSansGeorgian-Regular.ttf
- NotoSansGujarati-Regular.ttf
- - NotoSansGurmukhi-Regular.ttf
- NotoSansHebrew-Regular.ttf
- NotoSansKannada-Regular.ttf
- NotoSansKhmer-Regular.ttf
@@ -31,7 +30,6 @@ var:
- NotoSansMalayalam-Regular.ttf
- NotoSansMyanmar-Regular.ttf
- NotoSansOriya-Regular.ttf
- - NotoSansSinhala-Regular.ttf
- NotoSansTamil-Regular.ttf
- NotoSansTelugu-Regular.ttf
- NotoSansThaana-Regular.ttf
1
0
[tor-browser/tor-browser-91.4.0esr-11.0-1] Bug 27476: Implement about:torconnect captive portal within Tor Browser
by sysrqb@torproject.org 02 Dec '21
by sysrqb@torproject.org 02 Dec '21
02 Dec '21
commit bf9abfee292a439712f90288d9e5479fd841b479
Author: Richard Pospesel <richard(a)torproject.org>
Date: Wed Apr 28 23:09:34 2021 -0500
Bug 27476: Implement about:torconnect captive portal within Tor Browser
- implements new about:torconnect page as tor-launcher replacement
- adds tor connection status to url bar and tweaks UX when not online
- adds new torconnect component to browser
- tor process management functionality remains implemented in tor-launcher through the TorProtocolService module
- the onion pattern from about:tor migrated to an .inc.xhtml file now used by both about:tor and about:torconnect
- various design tweaks and resusability fixes to onion pattern
- adds warning/error box to about:preferences#tor when not connected to tor
- explicitly allows about:torconnect URIs to ignore Resist Fingerprinting (RFP)
- various tweaks to info-pages.inc.css for about:torconnect (also affects other firefox info pages)
---
browser/actors/NetErrorParent.jsm | 8 +
browser/base/content/browser-siteIdentity.js | 2 +-
browser/base/content/browser.js | 66 ++-
browser/base/content/browser.xhtml | 2 +
browser/base/content/certerror/aboutNetError.js | 12 +-
browser/base/content/navigator-toolbox.inc.xhtml | 1 +
browser/base/content/utilityOverlay.js | 8 +
browser/branding/alpha/content/jar.mn | 2 +
browser/branding/alpha/content/tor-styles.css | 13 +
browser/branding/nightly/content/jar.mn | 1 +
browser/branding/nightly/content/tor-styles.css | 13 +
browser/branding/official/content/jar.mn | 1 +
browser/branding/official/content/tor-styles.css | 14 +
browser/branding/tor-styles.inc.css | 87 ++++
browser/components/BrowserGlue.jsm | 37 +-
browser/components/about/AboutRedirector.cpp | 4 +
browser/components/about/components.conf | 1 +
browser/components/moz.build | 1 +
.../onionservices/HttpsEverywhereControl.jsm | 17 +-
browser/components/sessionstore/SessionStore.jsm | 4 +
browser/components/torconnect/TorConnectChild.jsm | 9 +
browser/components/torconnect/TorConnectParent.jsm | 144 ++++++
.../torconnect/content/aboutTorConnect.css | 159 +++++++
.../torconnect/content/aboutTorConnect.js | 302 ++++++++++++
.../torconnect/content/aboutTorConnect.xhtml | 45 ++
.../components/torconnect/content/onion-slash.svg | 13 +
browser/components/torconnect/content/onion.svg | 8 +
.../torconnect/content/torBootstrapUrlbar.js | 93 ++++
.../torconnect/content/torconnect-urlbar.css | 57 +++
.../torconnect/content/torconnect-urlbar.inc.xhtml | 10 +
browser/components/torconnect/jar.mn | 7 +
browser/components/torconnect/moz.build | 6 +
.../components/torpreferences/content/torPane.js | 123 +++++
.../torpreferences/content/torPane.xhtml | 34 ++
.../torpreferences/content/torPreferences.css | 123 +++++
browser/components/urlbar/UrlbarInput.jsm | 32 ++
browser/modules/TorConnect.jsm | 506 +++++++++++++++++++++
browser/modules/TorProcessService.jsm | 12 +
browser/modules/TorProtocolService.jsm | 58 ++-
browser/modules/TorStrings.jsm | 80 ++++
browser/modules/moz.build | 2 +
.../shared/identity-block/identity-block.inc.css | 7 +-
browser/themes/shared/jar.inc.mn | 2 +
browser/themes/shared/onionPattern.css | 31 ++
browser/themes/shared/onionPattern.inc.xhtml | 12 +
browser/themes/shared/onionPattern.svg | 22 +
browser/themes/shared/urlbar-searchbar.inc.css | 2 +
dom/base/Document.cpp | 51 ++-
dom/base/nsGlobalWindowOuter.cpp | 2 +
.../processsingleton/MainProcessSingleton.jsm | 5 +
toolkit/modules/AsyncPrefs.jsm | 1 +
toolkit/modules/RemotePageAccessManager.jsm | 16 +
toolkit/mozapps/update/UpdateService.jsm | 68 ++-
.../lib/environments/browser-window.js | 4 +
54 files changed, 2298 insertions(+), 42 deletions(-)
diff --git a/browser/actors/NetErrorParent.jsm b/browser/actors/NetErrorParent.jsm
index dfae068fd5c0..ba35962c943e 100644
--- a/browser/actors/NetErrorParent.jsm
+++ b/browser/actors/NetErrorParent.jsm
@@ -21,6 +21,10 @@ const { TelemetryController } = ChromeUtils.import(
"resource://gre/modules/TelemetryController.jsm"
);
+const { TorConnect } = ChromeUtils.import(
+ "resource:///modules/TorConnect.jsm"
+);
+
const PREF_SSL_IMPACT_ROOTS = [
"security.tls.version.",
"security.ssl3.",
@@ -350,6 +354,10 @@ class NetErrorParent extends JSWindowActorParent {
break;
}
}
+ break;
+ case "ShouldShowTorConnect":
+ return TorConnect.shouldShowTorConnect;
}
+ return undefined;
}
}
diff --git a/browser/base/content/browser-siteIdentity.js b/browser/base/content/browser-siteIdentity.js
index 1b2c7bcb22cf..2111e67c5d09 100644
--- a/browser/base/content/browser-siteIdentity.js
+++ b/browser/base/content/browser-siteIdentity.js
@@ -57,7 +57,7 @@ var gIdentityHandler = {
* RegExp used to decide if an about url should be shown as being part of
* the browser UI.
*/
- _secureInternalPages: (AppConstants.TOR_BROWSER_UPDATE ? /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|ion|tor|tbupdate)(?:[?#]|$)/i : /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|ion|tor)(?:[?#]|$)/i),
+ _secureInternalPages: (AppConstants.TOR_BROWSER_UPDATE ? /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|ion|tor|tbupdate)(?:[?#]|$)/i : /^(?:accounts|addons|cache|certificate|config|crashes|downloads|license|logins|preferences|protections|rights|sessionrestore|support|welcomeback|ion|tor|torconnect)(?:[?#]|$)/i),
/**
* Whether the established HTTPS connection is considered "broken".
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 090de22cb294..cfbbdc7cb9e0 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -81,6 +81,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
TabModalPrompt: "chrome://global/content/tabprompts.jsm",
TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm",
TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.jsm",
+ TorConnect: "resource:///modules/TorConnect.jsm",
Translation: "resource:///modules/translation/TranslationParent.jsm",
OnionAliasStore: "resource:///modules/OnionAliasStore.jsm",
UITour: "resource:///modules/UITour.jsm",
@@ -646,6 +647,7 @@ var gPageIcons = {
var gInitialPages = [
"about:tor",
+ "about:torconnect",
"about:blank",
"about:newtab",
"about:home",
@@ -1866,6 +1868,8 @@ var gBrowserInit = {
}
this._loadHandled = true;
+
+ TorBootstrapUrlbar.init();
},
_cancelDelayedStartup() {
@@ -2416,32 +2420,48 @@ var gBrowserInit = {
let defaultArgs = BrowserHandler.defaultArgs;
- // If the given URI is different from the homepage, we want to load it.
- if (uri != defaultArgs) {
- AboutNewTab.noteNonDefaultStartup();
+ // figure out which URI to actually load (or a Promise to get the uri)
+ uri = ((uri) => {
+ // If the given URI is different from the homepage, we want to load it.
+ if (uri != defaultArgs) {
+ AboutNewTab.noteNonDefaultStartup();
+
+ if (uri instanceof Ci.nsIArray) {
+ // Transform the nsIArray of nsISupportsString's into a JS Array of
+ // JS strings.
+ return Array.from(
+ uri.enumerate(Ci.nsISupportsString),
+ supportStr => supportStr.data
+ );
+ } else if (uri instanceof Ci.nsISupportsString) {
+ return uri.data;
+ }
+ return uri;
+ }
- if (uri instanceof Ci.nsIArray) {
- // Transform the nsIArray of nsISupportsString's into a JS Array of
- // JS strings.
- return Array.from(
- uri.enumerate(Ci.nsISupportsString),
- supportStr => supportStr.data
- );
- } else if (uri instanceof Ci.nsISupportsString) {
- return uri.data;
+ // The URI appears to be the the homepage. We want to load it only if
+ // session restore isn't about to override the homepage.
+ let willOverride = SessionStartup.willOverrideHomepage;
+ if (typeof willOverride == "boolean") {
+ return willOverride ? null : uri;
}
- return uri;
- }
+ return willOverride.then(willOverrideHomepage =>
+ willOverrideHomepage ? null : uri
+ );
+ })(uri);
+
+ // if using TorConnect, convert these uris to redirects
+ if (TorConnect.shouldShowTorConnect) {
+ return Promise.resolve(uri).then((uri) => {
+ if (uri == null) {
+ uri = [];
+ }
- // The URI appears to be the the homepage. We want to load it only if
- // session restore isn't about to override the homepage.
- let willOverride = SessionStartup.willOverrideHomepage;
- if (typeof willOverride == "boolean") {
- return willOverride ? null : uri;
+ uri = TorConnect.getURIsToLoad(uri);
+ return uri;
+ });
}
- return willOverride.then(willOverrideHomepage =>
- willOverrideHomepage ? null : uri
- );
+ return uri;
})());
},
@@ -2508,6 +2528,8 @@ var gBrowserInit = {
OnionAuthPrompt.uninit();
+ TorBootstrapUrlbar.uninit();
+
gAccessibilityServiceIndicator.uninit();
if (gToolbarKeyNavEnabled) {
diff --git a/browser/base/content/browser.xhtml b/browser/base/content/browser.xhtml
index 65445a099148..394a46414018 100644
--- a/browser/base/content/browser.xhtml
+++ b/browser/base/content/browser.xhtml
@@ -10,6 +10,7 @@
override rules using selectors with the same specificity. This applies to
both "content" and "skin" packages, which bug 1385444 will unify later. -->
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="chrome://branding/content/tor-styles.css" type="text/css"?>
<!-- While these stylesheets are defined in Toolkit, they are only used in the
main browser window, so we can load them here. Bug 1474241 is on file to
@@ -113,6 +114,7 @@
Services.scriptloader.loadSubScript("chrome://browser/content/search/searchbar.js", this);
Services.scriptloader.loadSubScript("chrome://torbutton/content/tor-circuit-display.js", this);
Services.scriptloader.loadSubScript("chrome://torbutton/content/torbutton.js", this);
+ Services.scriptloader.loadSubScript("chrome://browser/content/torconnect/torBootstrapUrlbar.js", this);
window.onload = gBrowserInit.onLoad.bind(gBrowserInit);
window.onunload = gBrowserInit.onUnload.bind(gBrowserInit);
diff --git a/browser/base/content/certerror/aboutNetError.js b/browser/base/content/certerror/aboutNetError.js
index e5b223025a8b..60f602ba6530 100644
--- a/browser/base/content/certerror/aboutNetError.js
+++ b/browser/base/content/certerror/aboutNetError.js
@@ -240,7 +240,7 @@ function setErrorPageStrings(err) {
document.l10n.setAttributes(titleElement, title);
}
-function initPage() {
+async function initPage() {
// We show an offline support page in case of a system-wide error,
// when a user cannot connect to the internet and access the SUMO website.
// For example, clock error, which causes certerrors across the web or
@@ -259,6 +259,16 @@ function initPage() {
}
var err = getErrorCode();
+
+ // proxyConnectFailure because no-tor running daemon would return this error
+ if (
+ (err === "proxyConnectFailure") &&
+ (await RPMSendQuery("ShouldShowTorConnect"))
+ ) {
+ // pass orginal destination as redirect param
+ const encodedRedirect = encodeURIComponent(document.location.href);
+ document.location.replace(`about:torconnect?redirect=${encodedRedirect}`);
+ }
// List of error pages with an illustration.
let illustratedErrors = [
"malformedURI",
diff --git a/browser/base/content/navigator-toolbox.inc.xhtml b/browser/base/content/navigator-toolbox.inc.xhtml
index 1aad36ab3bfc..b881492864ae 100644
--- a/browser/base/content/navigator-toolbox.inc.xhtml
+++ b/browser/base/content/navigator-toolbox.inc.xhtml
@@ -331,6 +331,7 @@
data-l10n-id="urlbar-go-button"/>
<hbox id="page-action-buttons" context="pageActionContextMenu">
<toolbartabstop/>
+#include ../../components/torconnect/content/torconnect-urlbar.inc.xhtml
<hbox id="contextual-feature-recommendation" role="button" hidden="true">
<hbox id="cfr-label-container">
<label id="cfr-label"/>
diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js
index 342a92a766a4..3d22093119ca 100644
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -20,6 +20,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
ExtensionSettingsStore: "resource://gre/modules/ExtensionSettingsStore.jsm",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
ShellService: "resource:///modules/ShellService.jsm",
+ TorConnect: "resource:///modules/TorConnect.jsm",
});
XPCOMUtils.defineLazyGetter(this, "ReferrerInfo", () =>
@@ -336,6 +337,13 @@ function openUILinkIn(
aPostData,
aReferrerInfo
) {
+
+ // make sure users are not faced with the scary red 'tor isn't working' screen
+ // if they navigate to about:tor before bootstrapped
+ if (url === "about:tor" && TorConnect.shouldShowTorConnect) {
+ url = `about:torconnect?redirect=${encodeURIComponent("about:tor")}`;
+ }
+
var params;
if (arguments.length == 3 && typeof arguments[2] == "object") {
diff --git a/browser/branding/alpha/content/jar.mn b/browser/branding/alpha/content/jar.mn
index 6db01f74fd20..93ff6ecf736b 100644
--- a/browser/branding/alpha/content/jar.mn
+++ b/browser/branding/alpha/content/jar.mn
@@ -18,4 +18,6 @@ browser.jar:
content/branding/icon128.png (../default128.png)
content/branding/icon256.png (../default256.png)
content/branding/icon512.png (../default512.png)
+ content/branding/identity-icons-brand.svg
content/branding/aboutDialog.css
+* content/branding/tor-styles.css
diff --git a/browser/branding/alpha/content/tor-styles.css b/browser/branding/alpha/content/tor-styles.css
new file mode 100644
index 000000000000..14c1915ef871
--- /dev/null
+++ b/browser/branding/alpha/content/tor-styles.css
@@ -0,0 +1,13 @@
+%include ../../tor-styles.inc.css
+
+/* default theme*/
+:root,
+/* light theme*/
+:root:-moz-lwtheme-darktext {
+ --tor-branding-color: var(--teal-70);
+}
+
+/* dark theme */
+:root:-moz-lwtheme-brighttext {
+ --tor-branding-color: var(--teal-60);
+}
\ No newline at end of file
diff --git a/browser/branding/nightly/content/jar.mn b/browser/branding/nightly/content/jar.mn
index 713d4c492475..93ff6ecf736b 100644
--- a/browser/branding/nightly/content/jar.mn
+++ b/browser/branding/nightly/content/jar.mn
@@ -20,3 +20,4 @@ browser.jar:
content/branding/icon512.png (../default512.png)
content/branding/identity-icons-brand.svg
content/branding/aboutDialog.css
+* content/branding/tor-styles.css
diff --git a/browser/branding/nightly/content/tor-styles.css b/browser/branding/nightly/content/tor-styles.css
new file mode 100644
index 000000000000..52e1761e5459
--- /dev/null
+++ b/browser/branding/nightly/content/tor-styles.css
@@ -0,0 +1,13 @@
+%include ../../tor-styles.inc.css
+
+/* default theme*/
+:root,
+/* light theme*/
+:root:-moz-lwtheme-darktext {
+ --tor-branding-color: var(--blue-60);
+}
+
+/* dark theme */
+:root:-moz-lwtheme-brighttext {
+ --tor-branding-color: var(--blue-40);
+}
\ No newline at end of file
diff --git a/browser/branding/official/content/jar.mn b/browser/branding/official/content/jar.mn
index 713d4c492475..93ff6ecf736b 100644
--- a/browser/branding/official/content/jar.mn
+++ b/browser/branding/official/content/jar.mn
@@ -20,3 +20,4 @@ browser.jar:
content/branding/icon512.png (../default512.png)
content/branding/identity-icons-brand.svg
content/branding/aboutDialog.css
+* content/branding/tor-styles.css
diff --git a/browser/branding/official/content/tor-styles.css b/browser/branding/official/content/tor-styles.css
new file mode 100644
index 000000000000..e4ccb5c767a9
--- /dev/null
+++ b/browser/branding/official/content/tor-styles.css
@@ -0,0 +1,14 @@
+%include ../../tor-styles.inc.css
+
+/* default theme*/
+:root,
+/* light theme*/
+:root:-moz-lwtheme-darktext {
+ --tor-branding-color: var(--purple-60);
+}
+
+/* dark theme */
+:root:-moz-lwtheme-brighttext {
+ --tor-branding-color: var(--purple-30);
+}
+
diff --git a/browser/branding/tor-styles.inc.css b/browser/branding/tor-styles.inc.css
new file mode 100644
index 000000000000..55dc9b6238b3
--- /dev/null
+++ b/browser/branding/tor-styles.inc.css
@@ -0,0 +1,87 @@
+:root {
+ /* photon colors, not all of them are available for whatever reason
+ in firefox, so here they are */
+
+ --magenta-50: #ff1ad9;
+ --magenta-60: #ed00b5;
+ --magenta-70: #b5007f;
+ --magenta-80: #7d004f;
+ --magenta-90: #440027;
+
+ --purple-30: #c069ff;
+ --purple-40: #ad3bff;
+ --purple-50: #9400ff;
+ --purple-60: #8000d7;
+ --purple-70: #6200a4;
+ --purple-80: #440071;
+ --purple-90: #25003e;
+
+ --blue-40: #45a1ff;
+ --blue-50: #0a84ff;
+ --blue-50-a30: rgba(10, 132, 255, 0.3);
+ --blue-60: #0060df;
+ --blue-70: #003eaa;
+ --blue-80: #002275;
+ --blue-90: #000f40;
+
+ --teal-50: #00feff;
+ --teal-60: #00c8d7;
+ --teal-70: #008ea4;
+ --teal-80: #005a71;
+ --teal-90: #002d3e;
+
+ --green-50: #30e60b;
+ --green-60: #12bc00;
+ --green-70: #058b00;
+ --green-80: #006504;
+ --green-90: #003706;
+
+ --yellow-50: #ffe900;
+ --yellow-60: #d7b600;
+ --yellow-70: #a47f00;
+ --yellow-80: #715100;
+ --yellow-90: #3e2800;
+
+ --red-50: #ff0039;
+ --red-60: #d70022;
+ --red-70: #a4000f;
+ --red-80: #5a0002;
+ --red-90: #3e0200;
+
+ --orange-50: #ff9400;
+ --orange-60: #d76e00;
+ --orange-70: #a44900;
+ --orange-80: #712b00;
+ --orange-90: #3e1300;
+
+ --grey-10: #f9f9fa;
+ --grey-10-a10: rgba(249, 249, 250, 0.1);
+ --grey-10-a20: rgba(249, 249, 250, 0.2);
+ --grey-10-a40: rgba(249, 249, 250, 0.4);
+ --grey-10-a60: rgba(249, 249, 250, 0.6);
+ --grey-10-a80: rgba(249, 249, 250, 0.8);
+ --grey-20: #ededf0;
+ --grey-30: #d7d7db;
+ --grey-40: #b1b1b3;
+ --grey-50: #737373;
+ --grey-60: #4a4a4f;
+ --grey-70: #38383d;
+ --grey-80: #2a2a2e;
+ --grey-90: #0c0c0d;
+ --grey-90-a05: rgba(12, 12, 13, 0.05);
+ --grey-90-a10: rgba(12, 12, 13, 0.1);
+ --grey-90-a20: rgba(12, 12, 13, 0.2);
+ --grey-90-a30: rgba(12, 12, 13, 0.3);
+ --grey-90-a40: rgba(12, 12, 13, 0.4);
+ --grey-90-a50: rgba(12, 12, 13, 0.5);
+ --grey-90-a60: rgba(12, 12, 13, 0.6);
+ --grey-90-a70: rgba(12, 12, 13, 0.7);
+ --grey-90-a80: rgba(12, 12, 13, 0.8);
+ --grey-90-a90: rgba(12, 12, 13, 0.9);
+
+ --ink-70: #363959;
+ --ink-80: #202340;
+ --ink-90: #0f1126;
+
+ --white-100: #ffffff;
+}
\ No newline at end of file
diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm
index 65d5ea9eae5b..5588d1463d94 100644
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -725,6 +725,20 @@ let JSWINDOWACTORS = {
allFrames: true,
},
+ TorConnect: {
+ parent: {
+ moduleURI: "resource:///modules/TorConnectParent.jsm",
+ },
+ child: {
+ moduleURI: "resource:///modules/TorConnectChild.jsm",
+ events: {
+ DOMWindowCreated: {},
+ },
+ },
+
+ matches: ["about:torconnect","about:torconnect?*"],
+ },
+
Translation: {
parent: {
moduleURI: "resource:///modules/translation/TranslationParent.jsm",
@@ -2522,7 +2536,28 @@ BrowserGlue.prototype = {
{
task: () => {
- OnionAliasStore.init();
+ const { TorConnect, TorConnectTopics } = ChromeUtils.import(
+ "resource:///modules/TorConnect.jsm"
+ );
+ if (!TorConnect.shouldShowTorConnect) {
+ // we will take this path when the user is using the legacy tor launcher or
+ // when Tor Browser didn't launch its own tor.
+ OnionAliasStore.init();
+ } else {
+ // this path is taken when using about:torconnect, we wait to init
+ // after we are bootstrapped and connected to tor
+ const topic = TorConnectTopics.BootstrapComplete;
+ let bootstrapObserver = {
+ observe(aSubject, aTopic, aData) {
+ if (aTopic === topic) {
+ OnionAliasStore.init();
+ // we only need to init once, so remove ourselves as an obvserver
+ Services.obs.removeObserver(this, topic);
+ }
+ }
+ };
+ Services.obs.addObserver(bootstrapObserver, topic);
+ }
},
},
diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp
index 323c1b6fb653..fd828a630c92 100644
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -128,6 +128,10 @@ static const RedirEntry kRedirMap[] = {
nsIAboutModule::URI_MUST_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT},
#endif
+ {"torconnect", "chrome://browser/content/torconnect/aboutTorConnect.xhtml",
+ nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
+ nsIAboutModule::URI_CAN_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
+ nsIAboutModule::HIDE_FROM_ABOUTABOUT},
};
static nsAutoCString GetAboutModuleName(nsIURI* aURI) {
diff --git a/browser/components/about/components.conf b/browser/components/about/components.conf
index 67f178ee23ff..0916bb75e1d5 100644
--- a/browser/components/about/components.conf
+++ b/browser/components/about/components.conf
@@ -26,6 +26,7 @@ pages = [
'robots',
'sessionrestore',
'tabcrashed',
+ 'torconnect',
'welcome',
'welcomeback',
]
diff --git a/browser/components/moz.build b/browser/components/moz.build
index 0ea2969e60b0..c30497374912 100644
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -55,6 +55,7 @@ DIRS += [
"syncedtabs",
"uitour",
"urlbar",
+ "torconnect",
"torpreferences",
"translation",
]
diff --git a/browser/components/onionservices/HttpsEverywhereControl.jsm b/browser/components/onionservices/HttpsEverywhereControl.jsm
index 525ed5233be7..d673de4cd6e5 100644
--- a/browser/components/onionservices/HttpsEverywhereControl.jsm
+++ b/browser/components/onionservices/HttpsEverywhereControl.jsm
@@ -41,6 +41,7 @@ const SECUREDROP_TOR_ONION_CHANNEL = {
class HttpsEverywhereControl {
constructor() {
this._extensionMessaging = null;
+ this._init();
}
async _sendMessage(type, object) {
@@ -61,7 +62,6 @@ class HttpsEverywhereControl {
* Installs the .tor.onion update channel in https-everywhere
*/
async installTorOnionUpdateChannel(retries = 5) {
- this._init();
// TODO: https-everywhere store is initialized asynchronously, so sending a message
// immediately results in a `store.get is undefined` error.
@@ -143,5 +143,20 @@ class HttpsEverywhereControl {
if (!this._extensionMessaging) {
this._extensionMessaging = new ExtensionMessaging();
}
+
+ // update all of the existing https-everywhere channels
+ setTimeout(async () => {
+ let pinnedChannels = await this._sendMessage("get_pinned_update_channels");
+ for(let channel of pinnedChannels.update_channels) {
+ this._sendMessage("update_update_channel", channel);
+ }
+
+ let storedChannels = await this._sendMessage("get_stored_update_channels");
+ for(let channel of storedChannels.update_channels) {
+ this._sendMessage("update_update_channel", channel);
+ }
+ }, 0);
+
+
}
}
diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm
index 2150c424d8b8..ddeb92378432 100644
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -186,6 +186,10 @@ ChromeUtils.defineModuleGetter(
"resource://gre/modules/sessionstore/SessionHistory.jsm"
);
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+
XPCOMUtils.defineLazyServiceGetters(this, {
gScreenManager: ["@mozilla.org/gfx/screenmanager;1", "nsIScreenManager"],
});
diff --git a/browser/components/torconnect/TorConnectChild.jsm b/browser/components/torconnect/TorConnectChild.jsm
new file mode 100644
index 000000000000..bd6dd549f156
--- /dev/null
+++ b/browser/components/torconnect/TorConnectChild.jsm
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, The Tor Project, Inc.
+
+var EXPORTED_SYMBOLS = ["TorConnectChild"];
+
+const { RemotePageChild } = ChromeUtils.import(
+ "resource://gre/actors/RemotePageChild.jsm"
+);
+
+class TorConnectChild extends RemotePageChild {}
diff --git a/browser/components/torconnect/TorConnectParent.jsm b/browser/components/torconnect/TorConnectParent.jsm
new file mode 100644
index 000000000000..526c588a423e
--- /dev/null
+++ b/browser/components/torconnect/TorConnectParent.jsm
@@ -0,0 +1,144 @@
+// Copyright (c) 2021, The Tor Project, Inc.
+
+var EXPORTED_SYMBOLS = ["TorConnectParent"];
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
+const { TorConnect, TorConnectTopics, TorConnectState } = ChromeUtils.import(
+ "resource:///modules/TorConnect.jsm"
+);
+
+const TorLauncherPrefs = Object.freeze({
+ quickstart: "extensions.torlauncher.quickstart",
+});
+
+/*
+This object is basically a marshalling interface between the TorConnect module
+and a particular about:torconnect page
+*/
+
+class TorConnectParent extends JSWindowActorParent {
+ constructor(...args) {
+ super(...args);
+
+ const self = this;
+
+ this.state = {
+ State: TorConnect.state,
+ StateChanged: false,
+ ErrorMessage: TorConnect.errorMessage,
+ ErrorDetails: TorConnect.errorDetails,
+ BootstrapProgress: TorConnect.bootstrapProgress,
+ BootstrapStatus: TorConnect.bootstrapStatus,
+ ShowCopyLog: TorConnect.logHasWarningOrError,
+ QuickStartEnabled: Services.prefs.getBoolPref(TorLauncherPrefs.quickstart, false),
+ };
+
+ // JSWindowActiveParent derived objects cannot observe directly, so create a member
+ // object to do our observing for us
+ //
+ // This object converts the various lifecycle events from the TorConnect module, and
+ // maintains a state object which we pass down to our about:torconnect page, which uses
+ // the state object to update its UI
+ this.torConnectObserver = {
+ observe(aSubject, aTopic, aData) {
+ let obj = aSubject?.wrappedJSObject;
+
+ // update our state struct based on received torconnect topics and forward on
+ // to aboutTorConnect.js
+ self.state.StateChanged = false;
+ switch(aTopic) {
+ case TorConnectTopics.StateChange: {
+ self.state.State = obj.state;
+ self.state.StateChanged = true;
+ // clear any previous error information if we are bootstrapping
+ if (self.state.State === TorConnectState.Bootstrapping) {
+ self.state.ErrorMessage = null;
+ self.state.ErrorDetails = null;
+ }
+ break;
+ }
+ case TorConnectTopics.BootstrapProgress: {
+ self.state.BootstrapProgress = obj.progress;
+ self.state.BootstrapStatus = obj.status;
+ self.state.ShowCopyLog = obj.hasWarnings;
+ break;
+ }
+ case TorConnectTopics.BootstrapComplete: {
+ // noop
+ break;
+ }
+ case TorConnectTopics.BootstrapError: {
+ self.state.ErrorMessage = obj.message;
+ self.state.ErrorDetails = obj.details;
+ self.state.ShowCopyLog = true;
+ break;
+ }
+ case TorConnectTopics.FatalError: {
+ // TODO: handle
+ break;
+ }
+ case "nsPref:changed": {
+ if (aData === TorLauncherPrefs.quickstart) {
+ self.state.QuickStartEnabled = Services.prefs.getBoolPref(TorLauncherPrefs.quickstart);
+ }
+ break;
+ }
+ default: {
+ console.log(`TorConnect: unhandled observe topic '${aTopic}'`);
+ }
+ }
+
+ self.sendAsyncMessage("torconnect:state-change", self.state);
+ },
+ };
+
+ // observe all of the torconnect:.* topics
+ for (const key in TorConnectTopics) {
+ const topic = TorConnectTopics[key];
+ Services.obs.addObserver(this.torConnectObserver, topic);
+ }
+ Services.prefs.addObserver(TorLauncherPrefs.quickstart, this.torConnectObserver);
+ }
+
+ willDestroy() {
+ // stop observing all of our torconnect:.* topics
+ for (const key in TorConnectTopics) {
+ const topic = TorConnectTopics[key];
+ Services.obs.removeObserver(this.torConnectObserver, topic);
+ }
+ Services.prefs.removeObserver(TorLauncherPrefs.quickstart, this.torConnectObserver);
+ }
+
+ receiveMessage(message) {
+ switch (message.name) {
+ case "torconnect:set-quickstart":
+ Services.prefs.setBoolPref(TorLauncherPrefs.quickstart, message.data);
+ break;
+ case "torconnect:open-tor-preferences":
+ TorConnect.openTorPreferences();
+ break;
+ case "torconnect:copy-tor-logs":
+ return TorConnect.copyTorLogs();
+ case "torconnect:cancel-bootstrap":
+ TorConnect.cancelBootstrap();
+ break;
+ case "torconnect:begin-bootstrap":
+ TorConnect.beginBootstrap();
+ break;
+ case "torconnect:get-init-args":
+ // called on AboutTorConnect.init(), pass down all state data it needs to init
+
+ // pretend this is a state transition on init
+ // so we always get fresh UI
+ this.state.StateChanged = true;
+ return {
+ TorStrings: TorStrings,
+ TorConnectState: TorConnectState,
+ Direction: Services.locale.isAppLocaleRTL ? "rtl" : "ltr",
+ State: this.state,
+ };
+ }
+ return undefined;
+ }
+}
diff --git a/browser/components/torconnect/content/aboutTorConnect.css b/browser/components/torconnect/content/aboutTorConnect.css
new file mode 100644
index 000000000000..460ecb511fde
--- /dev/null
+++ b/browser/components/torconnect/content/aboutTorConnect.css
@@ -0,0 +1,159 @@
+
+/* Copyright (c) 2021, The Tor Project, Inc. */
+
+@import url("chrome://browser/skin/error-pages.css");
+@import url("chrome://branding/content/tor-styles.css");
+
+:root {
+ --onion-opacity: 1;
+ --onion-color: var(--card-outline-color);
+ --onion-radius: 75px;
+}
+
+/* override firefox's default blue focus coloring */
+:focus {
+ outline: none!important;
+ box-shadow: 0 0 0 3px var(--purple-30) !important;
+ border: 1px var(--purple-80) solid !important;
+}
+
+@media (prefers-color-scheme: dark)
+{
+ :focus {
+ box-shadow: 0 0 0 3px var(--purple-50)!important;
+ }
+}
+
+/* override firefox's default blue border on hover */
+input[type="checkbox"]:not(:disabled):hover {
+ border-color: var(--purple-70);
+}
+
+#connectButton,
+input[type="checkbox"]:not(:disabled) {
+ background-color: var(--purple-60)!important;
+ color: white;
+ fill: white;
+}
+
+#connectButton:hover,
+input[type="checkbox"]:not(:disabled):hover {
+ background-color: var(--purple-70)!important;
+ color: white;
+ fill: white;
+}
+
+#connectButton:active,
+input[type="checkbox"]:not(:disabled):active {
+ background-color: var(--purple-80)!important;
+ color: white;
+ fill: white;
+}
+
+#progressBackground {
+ position:fixed;
+ padding:0;
+ margin:0;
+ top:0;
+ left:0;
+ width: 0%;
+ height: 7px;
+ background-image: linear-gradient(90deg, rgb(20, 218, 221) 0%, rgb(128, 109, 236) 100%);
+ border-radius: 0;
+}
+
+#connectPageContainer {
+ margin-top: 10vh;
+ width: 50%;
+}
+
+#quickstartCheckbox, #quickstartCheckboxLabel {
+ vertical-align: middle;
+}
+
+#copyLogButton {
+ position: relative;
+}
+
+/* mirrors p element spacing */
+#copyLogContainer {
+ margin: 1em 0;
+ height: 1.2em;
+ min-height: 1.2em;
+}
+
+#copyLogLink {
+ position: relative;
+ display: inline-block;
+ color: var(--in-content-link-color);
+}
+
+/* hidden apparently only works if no display is set; who knew? */
+#copyLogLink[hidden="true"] {
+ display: none;
+}
+
+#copyLogLink:hover {
+ cursor:pointer;
+}
+
+/* This div:
+ - is centered over its parent
+ - centers its child
+ - has z-index above parent
+ - ignores mouse events from parent
+*/
+#copyLogTooltip {
+ pointer-events: none;
+ visibility: hidden;
+ display: flex;
+ justify-content: center;
+ white-space: nowrap;
+ width: 0;
+ position: absolute;
+
+ z-index: 1;
+ left: 50%;
+ bottom: calc(100% + 0.25em);
+}
+
+/* tooltip content (any content could go here) */
+#copyLogTooltipText {
+ background-color: var(--green-50);
+ color: var(--green-90);
+ border-radius: 2px;
+ padding: 4px;
+ line-height: 13px;
+ font: 11px sans-serif;
+ font-weight: 400;
+}
+
+/* our speech bubble tail */
+#copyLogTooltipText::after {
+ content: "";
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ margin-left: -4px;
+ border-width: 4px;
+ border-style: solid;
+ border-color: var(--green-50) transparent transparent transparent;
+}
+
+body {
+ padding: 0px !important;
+ justify-content: space-between;
+ background-color: var(--in-content-page-background);
+}
+
+.title {
+ background-image: url("chrome://browser/content/torconnect/onion.svg");
+ -moz-context-properties: fill, fill-opacity;
+ fill-opacity: var(--onion-opacity);
+ fill: var(--onion-color);
+}
+
+.title.error {
+ background-image: url("chrome://browser/content/torconnect/onion-slash.svg");
+}
+
diff --git a/browser/components/torconnect/content/aboutTorConnect.js b/browser/components/torconnect/content/aboutTorConnect.js
new file mode 100644
index 000000000000..b53f8b13cb80
--- /dev/null
+++ b/browser/components/torconnect/content/aboutTorConnect.js
@@ -0,0 +1,302 @@
+// Copyright (c) 2021, The Tor Project, Inc.
+
+/* eslint-env mozilla/frame-script */
+
+// populated in AboutTorConnect.init()
+let TorStrings = {};
+let TorConnectState = {};
+
+class AboutTorConnect {
+ selectors = Object.freeze({
+ textContainer: {
+ title: "div.title",
+ titleText: "h1.title-text",
+ },
+ progress: {
+ description: "p#connectShortDescText",
+ meter: "div#progressBackground",
+ },
+ copyLog: {
+ link: "span#copyLogLink",
+ tooltip: "div#copyLogTooltip",
+ tooltipText: "span#copyLogTooltipText",
+ },
+ quickstart: {
+ checkbox: "input#quickstartCheckbox",
+ label: "label#quickstartCheckboxLabel",
+ },
+ buttons: {
+ connect: "button#connectButton",
+ cancel: "button#cancelButton",
+ advanced: "button#advancedButton",
+ },
+ })
+
+ elements = Object.freeze({
+ title: document.querySelector(this.selectors.textContainer.title),
+ titleText: document.querySelector(this.selectors.textContainer.titleText),
+ progressDescription: document.querySelector(this.selectors.progress.description),
+ progressMeter: document.querySelector(this.selectors.progress.meter),
+ copyLogLink: document.querySelector(this.selectors.copyLog.link),
+ copyLogTooltip: document.querySelector(this.selectors.copyLog.tooltip),
+ copyLogTooltipText: document.querySelector(this.selectors.copyLog.tooltipText),
+ quickstartCheckbox: document.querySelector(this.selectors.quickstart.checkbox),
+ quickstartLabel: document.querySelector(this.selectors.quickstart.label),
+ connectButton: document.querySelector(this.selectors.buttons.connect),
+ cancelButton: document.querySelector(this.selectors.buttons.cancel),
+ advancedButton: document.querySelector(this.selectors.buttons.advanced),
+ })
+
+ // a redirect url can be passed as a query parameter for the page to
+ // forward us to once bootstrap completes (otherwise the window will just close)
+ redirect = null
+
+ beginBootstrap() {
+ this.hide(this.elements.connectButton);
+ this.show(this.elements.cancelButton);
+ this.elements.cancelButton.focus();
+ RPMSendAsyncMessage("torconnect:begin-bootstrap");
+ }
+
+ cancelBootstrap() {
+ RPMSendAsyncMessage("torconnect:cancel-bootstrap");
+ }
+
+ /*
+ Element helper methods
+ */
+
+ show(element) {
+ element.removeAttribute("hidden");
+ }
+
+ hide(element) {
+ element.setAttribute("hidden", "true");
+ }
+
+ setTitle(title, error) {
+ this.elements.titleText.textContent = title;
+ document.title = title;
+
+ if (error) {
+ this.elements.title.classList.add("error");
+ } else {
+ this.elements.title.classList.remove("error");
+ }
+ }
+
+ setProgress(description, visible, percent) {
+ this.elements.progressDescription.textContent = description;
+ if (visible) {
+ this.show(this.elements.progressMeter);
+ this.elements.progressMeter.style.width = `${percent}%`;
+ } else {
+ this.hide(this.elements.progressMeter);
+ }
+ }
+
+ /*
+ These methods update the UI based on the current TorConnect state
+ */
+
+ updateUI(state) {
+ console.log(state);
+
+ // calls update_$state()
+ this[`update_${state.State}`](state);
+ this.elements.quickstartCheckbox.checked = state.QuickStartEnabled;
+ }
+
+ /* Per-state updates */
+
+ update_Initial(state) {
+ const hasError = false;
+ const showProgressbar = false;
+
+ this.setTitle(TorStrings.torConnect.torConnect, hasError);
+ this.setProgress(TorStrings.settings.torPreferencesDescription, showProgressbar);
+ this.hide(this.elements.copyLogLink);
+ this.hide(this.elements.connectButton);
+ this.hide(this.elements.advancedButton);
+ this.hide(this.elements.cancelButton);
+ }
+
+ update_Configuring(state) {
+ const hasError = state.ErrorMessage != null;
+ const showProgressbar = false;
+
+ if (hasError) {
+ this.setTitle(state.ErrorMessage, hasError);
+ this.setProgress(state.ErrorDetails, showProgressbar);
+ this.show(this.elements.copyLogLink);
+ this.elements.connectButton.textContent = TorStrings.torConnect.tryAgain;
+ } else {
+ this.setTitle(TorStrings.torConnect.torConnect, hasError);
+ this.setProgress(TorStrings.settings.torPreferencesDescription, showProgressbar);
+ this.hide(this.elements.copyLogLink);
+ this.elements.connectButton.textContent = TorStrings.torConnect.torConnectButton;
+ }
+ this.show(this.elements.connectButton);
+ if (state.StateChanged) {
+ this.elements.connectButton.focus();
+ }
+ this.show(this.elements.advancedButton);
+ this.hide(this.elements.cancelButton);
+ }
+
+ update_AutoConfiguring(state) {
+ // TODO: noop until this state is used
+ }
+
+ update_Bootstrapping(state) {
+ const hasError = false;
+ const showProgressbar = true;
+
+ this.setTitle(state.BootstrapStatus ? state.BootstrapStatus : TorStrings.torConnect.torConnecting, hasError);
+ this.setProgress(TorStrings.settings.torPreferencesDescription, showProgressbar, state.BootstrapProgress);
+ if (state.ShowCopyLog) {
+ this.show(this.elements.copyLogLink);
+ } else {
+ this.hide(this.elements.copyLogLink);
+ }
+ this.hide(this.elements.connectButton);
+ this.hide(this.elements.advancedButton);
+ this.show(this.elements.cancelButton);
+ if (state.StateChanged) {
+ this.elements.cancelButton.focus();
+ }
+ }
+
+ update_Error(state) {
+ const hasError = true;
+ const showProgressbar = false;
+
+ this.setTitle(state.ErrorMessage, hasError);
+ this.setProgress(state.ErrorDetails, showProgressbar);
+ this.show(this.elements.copyLogLink);
+ this.elements.connectButton.textContent = TorStrings.torConnect.tryAgain;
+ this.show(this.elements.connectButton);
+ this.show(this.elements.advancedButton);
+ this.hide(this.elements.cancelButton);
+ }
+
+ update_FatalError(state) {
+ // TODO: noop until this state is used
+ }
+
+ update_Bootstrapped(state) {
+ const hasError = false;
+ const showProgressbar = true;
+
+ this.setTitle(TorStrings.torConnect.torConnected, hasError);
+ this.setProgress(TorStrings.settings.torPreferencesDescription, showProgressbar, 100);
+ this.hide(this.elements.connectButton);
+ this.hide(this.elements.advancedButton);
+ this.hide(this.elements.cancelButton);
+
+ // redirects page to the requested redirect url, removes about:torconnect
+ // from the page stack, so users cannot accidentally go 'back' to the
+ // now unresponsive page
+ window.location.replace(this.redirect);
+ }
+
+ update_Disabled(state) {
+ // TODO: we should probably have some UX here if a user goes to about:torconnect when
+ // it isn't in use (eg using tor-launcher or system tor)
+ }
+
+ async initElements(direction) {
+
+ document.documentElement.setAttribute("dir", direction);
+
+ // sets the text content while keeping the child elements intact
+ this.elements.copyLogLink.childNodes[0].nodeValue =
+ TorStrings.torConnect.copyLog;
+ this.elements.copyLogLink.addEventListener("click", async (event) => {
+ const copiedMessage = await RPMSendQuery("torconnect:copy-tor-logs");
+ this.elements.copyLogTooltipText.textContent = copiedMessage;
+ this.elements.copyLogTooltipText.style.visibility = "visible";
+
+ // clear previous timeout if one already exists
+ if (this.copyLogTimeoutId) {
+ clearTimeout(this.copyLogTimeoutId);
+ }
+
+ // hide tooltip after X ms
+ const TOOLTIP_TIMEOUT = 2000;
+ this.copyLogTimeoutId = setTimeout(() => {
+ this.elements.copyLogTooltipText.style.visibility = "hidden";
+ this.copyLogTimeoutId = 0;
+ }, TOOLTIP_TIMEOUT);
+ });
+
+ this.elements.quickstartCheckbox.addEventListener("change", () => {
+ const quickstart = this.elements.quickstartCheckbox.checked;
+ RPMSendAsyncMessage("torconnect:set-quickstart", quickstart);
+ });
+ this.elements.quickstartLabel.textContent = TorStrings.settings.quickstartCheckbox;
+
+ this.elements.connectButton.textContent =
+ TorStrings.torConnect.torConnectButton;
+ this.elements.connectButton.addEventListener("click", () => {
+ this.beginBootstrap();
+ });
+
+ this.elements.advancedButton.textContent = TorStrings.torConnect.torConfigure;
+ this.elements.advancedButton.addEventListener("click", () => {
+ RPMSendAsyncMessage("torconnect:open-tor-preferences");
+ });
+
+ this.elements.cancelButton.textContent = TorStrings.torConnect.cancel;
+ this.elements.cancelButton.addEventListener("click", () => {
+ this.cancelBootstrap();
+ });
+ }
+
+ initObservers() {
+ // TorConnectParent feeds us state blobs to we use to update our UI
+ RPMAddMessageListener("torconnect:state-change", ({ data }) => {
+ this.updateUI(data);
+ });
+ }
+
+ initKeyboardShortcuts() {
+ document.onkeydown = (evt) => {
+ // unfortunately it looks like we still haven't standardized keycodes to
+ // integers, so we must resort to a string compare here :(
+ // see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code for relevant documentation
+ if (evt.code === "Escape") {
+ this.cancelBootstrap();
+ }
+ };
+ }
+
+ async init() {
+ // see if a user has a final destination after bootstrapping
+ let params = new URLSearchParams(new URL(document.location.href).search);
+ if (params.has("redirect")) {
+ const encodedRedirect = params.get("redirect");
+ this.redirect = decodeURIComponent(encodedRedirect);
+ } else {
+ // if the user gets here manually or via the button in the urlbar
+ // then we will redirect to about:tor
+ this.redirect = "about:tor";
+ }
+
+ let args = await RPMSendQuery("torconnect:get-init-args");
+
+ // various constants
+ TorStrings = Object.freeze(args.TorStrings);
+ TorConnectState = Object.freeze(args.TorConnectState);
+
+ this.initElements(args.Direction);
+ this.initObservers();
+ this.initKeyboardShortcuts();
+
+ // populate UI based on current state
+ this.updateUI(args.State);
+ }
+}
+
+const aboutTorConnect = new AboutTorConnect();
+aboutTorConnect.init();
diff --git a/browser/components/torconnect/content/aboutTorConnect.xhtml b/browser/components/torconnect/content/aboutTorConnect.xhtml
new file mode 100644
index 000000000000..595bbdf9a70a
--- /dev/null
+++ b/browser/components/torconnect/content/aboutTorConnect.xhtml
@@ -0,0 +1,45 @@
+<!-- Copyright (c) 2021, The Tor Project, Inc. -->
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Security-Policy" content="default-src chrome:; object-src 'none'" />
+ <link rel="stylesheet" href="chrome://browser/skin/onionPattern.css" type="text/css" media="all" />
+ <link rel="stylesheet" href="chrome://browser/content/torconnect/aboutTorConnect.css" type="text/css" media="all" />
+ </head>
+ <body>
+ <div id="progressBackground"></div>
+ <div id="connectPageContainer" class="container">
+ <div id="text-container">
+ <div class="title">
+ <h1 class="title-text"/>
+ </div>
+ <div id="connectLongContent">
+ <div id="connectShortDesc">
+ <p id="connectShortDescText" />
+ </div>
+ </div>
+
+ <div id="copyLogContainer">
+ <span id="copyLogLink" hidden="true">
+ <div id="copyLogTooltip">
+ <span id="copyLogTooltipText"/>
+ </div>
+ </span>
+ </div>
+
+ <div id="quickstartContainer">
+ <input id="quickstartCheckbox" type="checkbox" />
+ <label id="quickstartCheckboxLabel" for="quickstartCheckbox"/>
+ </div>
+
+ <div id="connectButtonContainer" class="button-container">
+ <button id="advancedButton" hidden="true"></button>
+ <button id="cancelButton" hidden="true"></button>
+ <button id="connectButton" class="primary try-again" hidden="true"></button>
+ </div>
+ </div>
+ </div>
+#include ../../../themes/shared/onionPattern.inc.xhtml
+ </body>
+ <script src="chrome://browser/content/torconnect/aboutTorConnect.js"/>
+</html>
diff --git a/browser/components/torconnect/content/onion-slash.svg b/browser/components/torconnect/content/onion-slash.svg
new file mode 100644
index 000000000000..d049bcd39cae
--- /dev/null
+++ b/browser/components/torconnect/content/onion-slash.svg
@@ -0,0 +1,13 @@
+<svg viewBox="0 0 16 16" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
+ <g fill-opacity="context-fill-opacity" fill="context-fill">
+ <path d="m13.3034 13.3032c-1.3572 1.3573-3.2323 2.1968-5.3034 2.1968-4.14214 0-7.5-3.3579-7.5-7.5 0-2.07093.83935-3.94582 2.19643-5.30303l.82867.82861c-1.14502 1.14515-1.85322 2.72708-1.85322 4.47442 0 3.4949 2.83319 6.3281 6.32812 6.3281 1.74752 0 3.3296-.7083 4.4748-1.8536z"/>
+ <path d="m14.1137 12.3453c.8729-1.226 1.3863-2.72567 1.3863-4.3453 0-4.14214-3.3579-7.5-7.5-7.5-1.61963 0-3.11935.51339-4.34531 1.38631l.84258.84258c1.00297-.66783 2.2074-1.05701 3.50273-1.05701 3.4949 0 6.3281 2.83319 6.3281 6.32812 0 1.29533-.3892 2.4998-1.057 3.5027z"/>
+ <path d="m12.4902 10.7218c.4822-.79365.7598-1.7253.7598-2.72181 0-2.89949-2.3505-5.25-5.25001-5.25-.9965 0-1.92816.27764-2.72184.75978l.86063.86062c.558-.28671 1.19071-.44852 1.86121-.44852 2.25231 0 4.07811 1.82584 4.07811 4.07812 0 .67051-.1618 1.30322-.4485 1.86122z"/>
+ <path d="m11.7124 11.7122-.8287-.8286c-.738.738-1.75754 1.1945-2.88371 1.1945-2.25228 0-4.07812-1.8258-4.07812-4.07811 0-1.12605.45639-2.14551 1.19428-2.88349l-.82868-.82861c-.94994.95005-1.53748 2.26246-1.53748 3.7121 0 2.89951 2.35051 5.25001 5.25 5.25001 1.44979 0 2.76231-.5877 3.71241-1.5378z"/>
+ <path d="m5.87853 5.87883c-.5428.54288-.87853 1.29282-.87853 2.12117 0 1.65686 1.34315 3 3 3 .82844 0 1.57845-.3358 2.1213-.8787l-.82863-.8286c-.33083.33081-.78785.53543-1.29267.53543-1.00964 0-1.82812-.81848-1.82812-1.82813 0-.50476.20457-.96175.53533-1.29256z"/>
+ <path d="m9.8272 8.05881c.00062-.01952.00093-.03913.00093-.05881 0-1.00964-.81848-1.82812-1.82813-1.82812-.01968 0-.03928.00031-.05881.00093l-.98589-.9859c.32532-.12086.6773-.18691 1.0447-.18691 1.65686 0 3 1.34315 3 3 0 .3674-.066.71938-.1869 1.04471z"/>
+ <path d="m8 15.5c-4.14214 0-7.5-3.3579-7.5-7.5 0-2.07093.83935-3.94582 2.19643-5.30303l5.30357 5.30316z"/>
+ <path d="m8 6.23161v-5.73161c-1.61963 0-3.11935.51339-4.34531 1.38631z"/>
+ </g>
+ <path d="m14.1161 15.6245c-.0821.0001-.1634-.016-.2393-.0474-.0758-.0314-.1447-.0775-.2027-.1356l-12.749984-12.749c-.109266-.11882-.168406-.27526-.165071-.43666.003335-.16139.068886-.31525.182967-.42946.114078-.11421.267868-.17994.429258-.18345.16139-.00352.3179.05544.43685.16457l12.74998 12.75c.1168.1176.1824.2767.1824.4425s-.0656.3249-.1824.4425c-.058.058-.1269.1039-.2028.1352-.0759.0312-.1571.0471-.2392.0468z" fill="#ff0039"/>
+</svg>
diff --git a/browser/components/torconnect/content/onion.svg b/browser/components/torconnect/content/onion.svg
new file mode 100644
index 000000000000..382a061774aa
--- /dev/null
+++ b/browser/components/torconnect/content/onion.svg
@@ -0,0 +1,8 @@
+<svg fill="context-fill" fill-opacity="context-fill-opacity" viewBox="0 0 16 16" width="16" height="16" xmlns="http://www.w3.org/2000/svg">
+ <g clip-rule="evenodd" fill-rule="evenodd">
+ <path d="m11 8c0 1.65686-1.34314 3-3 3-1.65685 0-3-1.34314-3-3 0-1.65685 1.34315-3 3-3 1.65686 0 3 1.34315 3 3zm-1.17187 0c0 1.00965-.81848 1.82813-1.82813 1.82813-1.00964 0-1.82812-.81848-1.82812-1.82813 0-1.00964.81848-1.82812 1.82812-1.82812 1.00965 0 1.82813.81848 1.82813 1.82812z"/>
+ <path d="m7.99999 13.25c2.89951 0 5.25001-2.3505 5.25001-5.25001 0-2.89949-2.3505-5.25-5.25001-5.25-2.89949 0-5.25 2.35051-5.25 5.25 0 2.89951 2.35051 5.25001 5.25 5.25001zm0-1.1719c2.25231 0 4.07811-1.8258 4.07811-4.07811 0-2.25228-1.8258-4.07812-4.07811-4.07812-2.25228 0-4.07812 1.82584-4.07812 4.07812 0 2.25231 1.82584 4.07811 4.07812 4.07811z"/>
+ <path d="m8 15.5c4.1421 0 7.5-3.3579 7.5-7.5 0-4.14214-3.3579-7.5-7.5-7.5-4.14214 0-7.5 3.35786-7.5 7.5 0 4.1421 3.35786 7.5 7.5 7.5zm0-1.1719c3.4949 0 6.3281-2.8332 6.3281-6.3281 0-3.49493-2.8332-6.32812-6.3281-6.32812-3.49493 0-6.32812 2.83319-6.32812 6.32812 0 3.4949 2.83319 6.3281 6.32812 6.3281z"/>
+ </g>
+ <path d="m.5 8c0 4.1421 3.35786 7.5 7.5 7.5v-15c-4.14214 0-7.5 3.35786-7.5 7.5z"/>
+</svg>
\ No newline at end of file
diff --git a/browser/components/torconnect/content/torBootstrapUrlbar.js b/browser/components/torconnect/content/torBootstrapUrlbar.js
new file mode 100644
index 000000000000..e6a88490f33d
--- /dev/null
+++ b/browser/components/torconnect/content/torBootstrapUrlbar.js
@@ -0,0 +1,93 @@
+// Copyright (c) 2021, The Tor Project, Inc.
+
+"use strict";
+
+const { TorConnect, TorConnectTopics, TorConnectState } = ChromeUtils.import(
+ "resource:///modules/TorConnect.jsm"
+);
+const { TorStrings } = ChromeUtils.import(
+ "resource:///modules/TorStrings.jsm"
+);
+
+var TorBootstrapUrlbar = {
+ selectors: Object.freeze({
+ torConnect: {
+ box: "hbox#torconnect-box",
+ label: "label#torconnect-label",
+ },
+ }),
+
+ elements: null,
+
+ updateTorConnectBox: function(state) {
+ switch(state)
+ {
+ case TorConnectState.Initial:
+ case TorConnectState.Configuring:
+ case TorConnectState.AutoConfiguring:
+ case TorConnectState.Error:
+ case TorConnectState.FatalError: {
+ this.elements.torConnectBox.removeAttribute("hidden");
+ this.elements.torConnectLabel.textContent =
+ TorStrings.torConnect.torNotConnectedConcise;
+ this.elements.inputContainer.setAttribute("torconnect", "offline");
+ break;
+ }
+ case TorConnectState.Bootstrapping: {
+ this.elements.torConnectBox.removeAttribute("hidden");
+ this.elements.torConnectLabel.textContent =
+ TorStrings.torConnect.torConnectingConcise;
+ this.elements.inputContainer.setAttribute("torconnect", "connecting");
+ break;
+ }
+ case TorConnectState.Bootstrapped: {
+ this.elements.torConnectBox.removeAttribute("hidden");
+ this.elements.torConnectLabel.textContent =
+ TorStrings.torConnect.torConnectedConcise;
+ this.elements.inputContainer.setAttribute("torconnect", "connected");
+ // hide torconnect box after 5 seconds
+ setTimeout(() => {
+ this.elements.torConnectBox.setAttribute("hidden", "true");
+ }, 5000);
+ break;
+ }
+ case TorConnectState.Disabled: {
+ this.elements.torConnectBox.setAttribute("hidden", "true");
+ break;
+ }
+ default:
+ break;
+ }
+ },
+
+ observe: function(aSubject, aTopic, aData) {
+ if (aTopic === TorConnectTopics.StateChange) {
+ const obj = aSubject?.wrappedJSObject;
+ this.updateTorConnectBox(obj?.state);
+ }
+ },
+
+ init: function() {
+ if (TorConnect.shouldShowTorConnect) {
+ // browser isn't populated until init
+ this.elements = Object.freeze({
+ torConnectBox: browser.ownerGlobal.document.querySelector(this.selectors.torConnect.box),
+ torConnectLabel: browser.ownerGlobal.document.querySelector(this.selectors.torConnect.label),
+ inputContainer: gURLBar._inputContainer,
+ })
+ this.elements.torConnectBox.addEventListener("click", () => {
+ TorConnect.openTorConnect();
+ });
+ Services.obs.addObserver(this, TorConnectTopics.StateChange);
+ this.observing = true;
+ this.updateTorConnectBox(TorConnect.state);
+ }
+ },
+
+ uninit: function() {
+ if (this.observing) {
+ Services.obs.removeObserver(this, TorConnectTopics.StateChange);
+ }
+ },
+};
+
diff --git a/browser/components/torconnect/content/torconnect-urlbar.css b/browser/components/torconnect/content/torconnect-urlbar.css
new file mode 100644
index 000000000000..5aabcffedbd0
--- /dev/null
+++ b/browser/components/torconnect/content/torconnect-urlbar.css
@@ -0,0 +1,57 @@
+/*
+ ensure our torconnect button is always visible (same rule as for the bookmark button)
+*/
+hbox.urlbar-page-action#torconnect-box {
+ display: -moz-inline-box!important;
+ height: 28px;
+}
+
+label#torconnect-label {
+ line-height: 28px;
+ margin: 0;
+ opacity: 0.6;
+ padding: 0 0.5em;
+}
+
+/* set appropriate sizes for the non-standard ui densities */
+:root[uidensity=compact] hbox.urlbar-page-action#torconnect-box {
+ height: 24px;
+}
+:root[uidensity=compact] label#torconnect-label {
+ line-height: 24px;
+}
+
+
+:root[uidensity=touch] hbox.urlbar-page-action#torconnect-box {
+ height: 30px;
+}
+:root[uidensity=touch] label#torconnect-label {
+ line-height: 30px;
+}
+
+
+/* hide when hidden attribute is set */
+hbox.urlbar-page-action#torconnect-box[hidden="true"],
+/* hide when user is typing in URL bar */
+#urlbar[usertyping] > #urlbar-input-container > #page-action-buttons > #torconnect-box {
+ display: none!important;
+}
+
+/* hide urlbar's placeholder text when not connectd to tor */
+hbox#urlbar-input-container[torconnect="offline"] input#urlbar-input::placeholder,
+hbox#urlbar-input-container[torconnect="connecting"] input#urlbar-input::placeholder {
+ opacity: 0;
+}
+
+/* hide search suggestions when not connected to tor */
+hbox#urlbar-input-container[torconnect="offline"] + vbox.urlbarView,
+hbox#urlbar-input-container[torconnect="connecting"] + vbox.urlbarView {
+ display: none!important;
+}
+
+/* hide search icon when we are not connected to tor */
+hbox#urlbar-input-container[torconnect="offline"] > #identity-box[pageproxystate="invalid"] > #identity-icon,
+hbox#urlbar-input-container[torconnect="connecting"] > #identity-box[pageproxystate="invalid"] > #identity-icon
+{
+ display: none!important;
+}
diff --git a/browser/components/torconnect/content/torconnect-urlbar.inc.xhtml b/browser/components/torconnect/content/torconnect-urlbar.inc.xhtml
new file mode 100644
index 000000000000..60e985a72691
--- /dev/null
+++ b/browser/components/torconnect/content/torconnect-urlbar.inc.xhtml
@@ -0,0 +1,10 @@
+# Copyright (c) 2021, The Tor Project, Inc.
+
+<hbox id="torconnect-box"
+ class="urlbar-icon-wrapper urlbar-page-action"
+ role="status"
+ hidden="true">
+ <hbox id="torconnect-container">
+ <label id="torconnect-label"/>
+ </hbox>
+</hbox>
\ No newline at end of file
diff --git a/browser/components/torconnect/jar.mn b/browser/components/torconnect/jar.mn
new file mode 100644
index 000000000000..ed8a4de299b2
--- /dev/null
+++ b/browser/components/torconnect/jar.mn
@@ -0,0 +1,7 @@
+browser.jar:
+ content/browser/torconnect/torBootstrapUrlbar.js (content/torBootstrapUrlbar.js)
+ content/browser/torconnect/aboutTorConnect.css (content/aboutTorConnect.css)
+* content/browser/torconnect/aboutTorConnect.xhtml (content/aboutTorConnect.xhtml)
+ content/browser/torconnect/aboutTorConnect.js (content/aboutTorConnect.js)
+ content/browser/torconnect/onion.svg (content/onion.svg)
+ content/browser/torconnect/onion-slash.svg (content/onion-slash.svg)
diff --git a/browser/components/torconnect/moz.build b/browser/components/torconnect/moz.build
new file mode 100644
index 000000000000..eb29c31a4243
--- /dev/null
+++ b/browser/components/torconnect/moz.build
@@ -0,0 +1,6 @@
+JAR_MANIFESTS += ['jar.mn']
+
+EXTRA_JS_MODULES += [
+ 'TorConnectChild.jsm',
+ 'TorConnectParent.jsm',
+]
diff --git a/browser/components/torpreferences/content/torPane.js b/browser/components/torpreferences/content/torPane.js
index 49054b5dac6a..1f169cbe1a55 100644
--- a/browser/components/torpreferences/content/torPane.js
+++ b/browser/components/torpreferences/content/torPane.js
@@ -1,9 +1,15 @@
"use strict";
+/* global Services */
+
const { TorProtocolService } = ChromeUtils.import(
"resource:///modules/TorProtocolService.jsm"
);
+const { TorConnect, TorConnectTopics, TorConnectState } = ChromeUtils.import(
+ "resource:///modules/TorConnect.jsm"
+);
+
const {
TorBridgeSource,
TorBridgeSettings,
@@ -51,6 +57,10 @@ const { parsePort, parseBridgeStrings, parsePortList } = ChromeUtils.import(
"chrome://browser/content/torpreferences/parseFunctions.jsm"
);
+const TorLauncherPrefs = {
+ quickstart: "extensions.torlauncher.quickstart",
+}
+
/*
Tor Pane
@@ -62,11 +72,21 @@ const gTorPane = (function() {
category: {
title: "label#torPreferences-labelCategory",
},
+ messageBox: {
+ box: "div#torPreferences-connectMessageBox",
+ message: "td#torPreferences-connectMessageBox-message",
+ button: "button#torPreferences-connectMessageBox-button",
+ },
torPreferences: {
header: "h1#torPreferences-header",
description: "span#torPreferences-description",
learnMore: "label#torPreferences-learnMore",
},
+ quickstart: {
+ header: "h2#torPreferences-quickstart-header",
+ description: "span#torPreferences-quickstart-description",
+ enableQuickstartCheckbox: "checkbox#torPreferences-quickstart-toggle",
+ },
bridges: {
header: "h2#torPreferences-bridges-header",
description: "span#torPreferences-bridges-description",
@@ -112,6 +132,10 @@ const gTorPane = (function() {
let retval = {
// cached frequently accessed DOM elements
+ _messageBox: null,
+ _messageBoxMessage: null,
+ _messageBoxButton: null,
+ _enableQuickstartCheckbox: null,
_useBridgeCheckbox: null,
_bridgeSelectionRadiogroup: null,
_builtinBridgeOption: null,
@@ -161,6 +185,51 @@ const gTorPane = (function() {
let prefpane = document.getElementById("mainPrefPane");
+ // 'Connect to Tor' Message Bar
+
+ this._messageBox = prefpane.querySelector(selectors.messageBox.box);
+ this._messageBoxMessage = prefpane.querySelector(selectors.messageBox.message);
+ this._messageBoxButton = prefpane.querySelector(selectors.messageBox.button);
+ // wire up connect button
+ this._messageBoxButton.addEventListener("click", () => {
+ TorConnect.beginBootstrap();
+ TorConnect.openTorConnect();
+ });
+
+ this._populateMessagebox = () => {
+ if (TorConnect.shouldShowTorConnect &&
+ TorConnect.state === TorConnectState.Configuring) {
+ // set messagebox style and text
+ if (TorProtocolService.torBootstrapErrorOccurred()) {
+ this._messageBox.parentNode.style.display = null;
+ this._messageBox.className = "error";
+ this._messageBoxMessage.innerText = TorStrings.torConnect.tryAgainMessage;
+ this._messageBoxButton.innerText = TorStrings.torConnect.tryAgain;
+ } else {
+ this._messageBox.parentNode.style.display = null;
+ this._messageBox.className = "warning";
+ this._messageBoxMessage.innerText = TorStrings.torConnect.connectMessage;
+ this._messageBoxButton.innerText = TorStrings.torConnect.torConnectButton;
+ }
+ } else {
+ // we need to explicitly hide the groupbox, as switching between
+ // the tor pane and other panes will 'unhide' (via the 'hidden'
+ // attribute) the groupbox, offsetting all of the content down
+ // by the groupbox's margin (even if content is 0 height)
+ this._messageBox.parentNode.style.display = "none";
+ this._messageBox.className = "hidden";
+ this._messageBoxMessage.innerText = "";
+ this._messageBoxButton.innerText = "";
+ }
+ }
+ this._populateMessagebox();
+ Services.obs.addObserver(this, TorConnectTopics.StateChange);
+
+ // update the messagebox whenever we come back to the page
+ window.addEventListener("focus", val => {
+ this._populateMessagebox();
+ });
+
// Heading
prefpane.querySelector(selectors.torPreferences.header).innerText =
TorStrings.settings.torPreferencesHeading;
@@ -177,6 +246,26 @@ const gTorPane = (function() {
);
}
+ // Quickstart
+ prefpane.querySelector(selectors.quickstart.header).innerText =
+ TorStrings.settings.quickstartHeading;
+ prefpane.querySelector(selectors.quickstart.description).textContent =
+ TorStrings.settings.quickstartDescription;
+
+ this._enableQuickstartCheckbox = prefpane.querySelector(
+ selectors.quickstart.enableQuickstartCheckbox
+ );
+ this._enableQuickstartCheckbox.setAttribute(
+ "label",
+ TorStrings.settings.quickstartCheckbox
+ );
+ this._enableQuickstartCheckbox.addEventListener("command", e => {
+ const checked = this._enableQuickstartCheckbox.checked;
+ Services.prefs.setBoolPref(TorLauncherPrefs.quickstart, checked);
+ });
+ this._enableQuickstartCheckbox.checked = Services.prefs.getBoolPref(TorLauncherPrefs.quickstart);
+ Services.prefs.addObserver(TorLauncherPrefs.quickstart, this);
+
// Bridge setup
prefpane.querySelector(selectors.bridges.header).innerText =
TorStrings.settings.bridgesHeading;
@@ -526,6 +615,18 @@ const gTorPane = (function() {
init() {
this._populateXUL();
+
+ let onUnload = () => {
+ window.removeEventListener("unload", onUnload);
+ gTorPane.uninit();
+ };
+ window.addEventListener("unload", onUnload);
+ },
+
+ uninit() {
+ // unregister our observer topics
+ Services.obs.removeObserver(TorSettingsTopics.SettingChanged, this);
+ Services.obs.removeObserver(TorConnectTopics.StateChange, this);
},
// whether the page should be present in about:preferences
@@ -537,6 +638,28 @@ const gTorPane = (function() {
// Callbacks
//
+ observe(subject, topic, data) {
+ switch (topic) {
+ // triggered when a TorSettings param has changed
+ case TorSettingsTopics.SettingChanged: {
+ let obj = subject?.wrappedJSObject;
+ switch(data) {
+ case TorSettingsData.QuickStartEnabled: {
+ this._enableQuickstartCheckbox.checked = obj.value;
+ break;
+ }
+ }
+ break;
+ }
+ // triggered when tor connect state changes and we may
+ // need to update the messagebox
+ case TorConnectTopics.StateChange: {
+ this._populateMessagebox();
+ break;
+ }
+ }
+ },
+
// callback when using bridges toggled
onToggleBridge(enabled) {
this._useBridgeCheckbox.checked = enabled;
diff --git a/browser/components/torpreferences/content/torPane.xhtml b/browser/components/torpreferences/content/torPane.xhtml
index 3c966b2b3726..7c8071f2cf10 100644
--- a/browser/components/torpreferences/content/torPane.xhtml
+++ b/browser/components/torpreferences/content/torPane.xhtml
@@ -3,6 +3,29 @@
<script type="application/javascript"
src="chrome://browser/content/torpreferences/torPane.js"/>
<html:template id="template-paneTor">
+
+<!-- Tor Connect Message Box -->
+<groupbox data-category="paneTor" hidden="true">
+ <html:div id="torPreferences-connectMessageBox"
+ class="subcategory"
+ data-category="paneTor"
+ hidden="true">
+ <html:table >
+ <html:tr>
+ <html:td>
+ <html:div id="torPreferences-connectMessageBox-icon"/>
+ </html:td>
+ <html:td id="torPreferences-connectMessageBox-message">
+ </html:td>
+ <html:td>
+ <html:button id="torPreferences-connectMessageBox-button">
+ </html:button>
+ </html:td>
+ </html:tr>
+ </html:table>
+ </html:div>
+</groupbox>
+
<hbox id="torPreferencesCategory"
class="subcategory"
data-category="paneTor"
@@ -18,6 +41,17 @@
</description>
</groupbox>
+<!-- Quickstart -->
+<groupbox id="torPreferences-quickstart-group"
+ data-category="paneTor"
+ hidden="true">
+ <html:h2 id="torPreferences-quickstart-header"/>
+ <description flex="1">
+ <html:span id="torPreferences-quickstart-description"/>
+ </description>
+ <checkbox id="torPreferences-quickstart-toggle"/>
+</groupbox>
+
<!-- Bridges -->
<groupbox id="torPreferences-bridges-group"
data-category="paneTor"
diff --git a/browser/components/torpreferences/content/torPreferences.css b/browser/components/torpreferences/content/torPreferences.css
index 4dac2c457823..a977648f0810 100644
--- a/browser/components/torpreferences/content/torPreferences.css
+++ b/browser/components/torpreferences/content/torPreferences.css
@@ -1,7 +1,130 @@
+@import url("chrome://branding/content/tor-styles.css");
+
#category-tor > .category-icon {
list-style-image: url("chrome://browser/content/torpreferences/torPreferencesIcon.svg");
}
+/* Connect Message Box */
+
+#torPreferences-connectMessageBox {
+ display: block;
+ position: relative;
+
+ width: auto;
+ min-height: 32px;
+ border-radius: 4px;
+ padding: 4px;
+}
+
+#torPreferences-connectMessageBox.hidden {
+ display: none;
+}
+
+#torPreferences-connectMessageBox.error {
+ background-color: var(--red-60);
+ color: white;
+}
+
+#torPreferences-connectMessageBox.warning {
+ background-color: var(--purple-50);
+ color: white;
+}
+
+#torPreferences-connectMessageBox table {
+ border-collapse: collapse;
+ width: 100%;
+}
+
+#torPreferences-connectMessageBox td {
+ vertical-align: top;
+ padding: 0px;
+}
+
+#torPreferences-connectMessageBox td:first-child {
+ width: 24px;
+}
+
+#torPreferences-connectMessageBox-icon {
+ display: block;
+ width: 16px;
+ height: 16px;
+ padding: 4px;
+
+ mask-repeat: no-repeat !important;
+ mask-size: 16px !important;
+ mask-position: 4px 4px !important;
+}
+
+#torPreferences-connectMessageBox.error #torPreferences-connectMessageBox-icon
+{
+ mask: url("chrome://browser/skin/onion-slash.svg");
+ background-color: white;
+}
+
+#torPreferences-connectMessageBox.warning #torPreferences-connectMessageBox-icon
+{
+ mask: url("chrome://browser/skin/onion.svg");
+ background-color: white;
+}
+
+#torPreferences-connectMessageBox-message {
+ display: block;
+ line-height: 16px;
+ font-size: 1.0em;
+ margin-right: 8px;
+ padding-left: 4px!important;
+ padding-top: 4px!important;
+}
+
+#torPreferences-connectMessageBox-button {
+ display: block;
+ width: auto;
+ height: 24px;
+ line-height: 24px;
+ min-height: 24px;
+ max-height: 24px;
+ min-width: 0px;
+ margin: 0px;
+
+ border-radius: 4px;
+ border: 0;
+ padding: 0px 1.25em;
+ margin-left: auto;
+ margin-right: 0px;
+
+ font-size: 0.9em;
+ font-weight: 600;
+ white-space: nowrap;
+
+ color: white;
+}
+
+#torPreferences-connectMessageBox.error #torPreferences-connectMessageBox-button {
+ background-color: var(--red-70);
+}
+
+#torPreferences-connectMessageBox.error #torPreferences-connectMessageBox-button:hover {
+ background-color: var(--red-80);
+}
+
+#torPreferences-connectMessageBox.error #torPreferences-connectMessageBox-button:active {
+ background-color: var(--red-90);
+}
+
+#torPreferences-connectMessageBox.warning #torPreferences-connectMessageBox-button {
+ background-color: var(--purple-70);
+}
+
+#torPreferences-connectMessageBox.warning #torPreferences-connectMessageBox-button:hover {
+ background-color: var(--purple-80);
+}
+
+#torPreferences-connectMessageBox.warning #torPreferences-connectMessageBox-button:active {
+ background-color: var(--purple-90);
+}
+
+/* Advanced Settings */
+
#torPreferences-advanced-grid {
display: grid;
grid-template-columns: auto 1fr;
diff --git a/browser/components/urlbar/UrlbarInput.jsm b/browser/components/urlbar/UrlbarInput.jsm
index 27261544127c..e7ab9db0a66c 100644
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -10,6 +10,34 @@ const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
+const { TorConnect } = ChromeUtils.import(
+ "resource:///modules/TorConnect.jsm"
+);
+
+// in certain scenarios we want user input uris to open in a new tab if they do so from the
+// about:torconnect tab
+function maybeUpdateOpenLocationForTorConnect(openUILinkWhere, currentURI, destinationURI) {
+ try {
+ // only open in new tab if:
+ if (// user is navigating away from about:torconnect
+ currentURI === "about:torconnect" &&
+ // we are trying to open in same tab
+ openUILinkWhere === "current" &&
+ // only if user still has not bootstrapped
+ TorConnect.shouldShowTorConnect &&
+ // and user is not just navigating to about:torconnect
+ destinationURI !== "about:torconnect") {
+ return "tab";
+ }
+ } catch (e) {
+ // swallow exception and fall through returning original so we don't accidentally break
+ // anything if an exception is thrown
+ console.log(e?.message ? e.message : e);
+ }
+
+ return openUILinkWhere;
+};
+
XPCOMUtils.defineLazyModuleGetters(this, {
AppConstants: "resource://gre/modules/AppConstants.jsm",
BrowserSearchTelemetry: "resource:///modules/BrowserSearchTelemetry.jsm",
@@ -2416,6 +2444,10 @@ class UrlbarInput {
this.selectionStart = this.selectionEnd = 0;
}
+ openUILinkWhere = maybeUpdateOpenLocationForTorConnect(
+ openUILinkWhere,
+ this.window.gBrowser.currentURI.asciiSpec,
+ url);
if (openUILinkWhere != "current") {
this.handleRevert();
}
diff --git a/browser/modules/TorConnect.jsm b/browser/modules/TorConnect.jsm
new file mode 100644
index 000000000000..19a3f595d490
--- /dev/null
+++ b/browser/modules/TorConnect.jsm
@@ -0,0 +1,506 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["TorConnect", "TorConnectTopics", "TorConnectState"];
+
+const { Services } = ChromeUtils.import(
+ "resource://gre/modules/Services.jsm"
+);
+
+const { BrowserWindowTracker } = ChromeUtils.import(
+ "resource:///modules/BrowserWindowTracker.jsm"
+);
+
+const { TorProtocolService, TorProcessStatus } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+
+const { TorLauncherUtil } = ChromeUtils.import(
+ "resource://torlauncher/modules/tl-util.jsm"
+);
+
+/* Browser observer topis */
+const BrowserTopics = Object.freeze({
+ ProfileAfterChange: "profile-after-change",
+});
+
+/* tor-launcher observer topics */
+const TorTopics = Object.freeze({
+ ProcessIsReady: "TorProcessIsReady",
+ BootstrapStatus: "TorBootstrapStatus",
+ BootstrapError: "TorBootstrapError",
+ ProcessExited: "TorProcessExited",
+ LogHasWarnOrErr: "TorLogHasWarnOrErr",
+});
+
+/* Relevant prefs used by tor-launcher */
+const TorLauncherPrefs = Object.freeze({
+ quickstart: "extensions.torlauncher.quickstart",
+ prompt_at_startup: "extensions.torlauncher.prompt_at_startup",
+});
+
+const TorConnectState = Object.freeze({
+ /* Our initial state */
+ Initial: "Initial",
+ /* In-between initial boot and bootstrapping, users can change tor network settings during this state */
+ Configuring: "Configuring",
+ /* Geo-location and setting bridges/etc */
+ AutoConfiguring: "AutoConfiguring",
+ /* Tor is bootstrapping */
+ Bootstrapping: "Bootstrapping",
+ /* Passthrough state back to Configuring or Fatal */
+ Error: "Error",
+ /* An unrecoverable error */
+ FatalError: "FatalError",
+ /* Final state, after successful bootstrap */
+ Bootstrapped: "Bootstrapped",
+ /* If we are using System tor or the legacy Tor-Launcher */
+ Disabled: "Disabled",
+});
+
+/*
+
+ TorConnect State Transitions
+
+ ┌──────────────────────┐
+ │ Disabled │
+ └──────────────────────┘
+ ▲
+ │ legacyOrSystemTor()
+ │
+ ┌──────────────────────┐
+ ┌────────────────────── │ Initial │ ───────────────────────────┐
+ │ └──────────────────────┘ │
+ │ │ │
+ │ │ beginBootstrap() │
+ │ ▼ │
+┌────────────────┐ │ bootstrapComplete() ┌────────────────────────────────────────────────┐ │ beginBootstrap()
+│ Bootstrapped │ ◀──┼────────────────────── │ Bootstrapping │ ◀┼─────────────────┐
+└────────────────┘ │ └────────────────────────────────────────────────┘ │ │
+ │ │ ▲ │ │ │
+ │ │ cancelBootstrap() │ beginBootstrap() └────┼─────────────┐ │
+ │ ▼ │ │ │ │
+ │ beginConfigure() ┌────────────────────────────────────────────────┐ │ │ │
+ └─────────────────────▶ │ │ │ │ │
+ │ │ │ │ │
+ beginConfigure() │ │ │ │ │
+ ┌──────────────────────────▶ │ Configuring │ │ │ │
+ │ │ │ │ │ │
+ │ │ │ │ │ │
+ │ ┌─────────────────────▶ │ │ │ │ │
+ │ │ └────────────────────────────────────────────────┘ │ │ │
+ │ │ │ │ │ │ │
+ │ │ cancelAutoconfigure() │ autoConfigure() │ ┌────┼─────────────┼───┘
+ │ │ ▼ │ │ │ │
+ │ │ ┌──────────────────────┐ │ │ │ │
+ │ └────────────────────── │ AutoConfiguring │ ─┼────────────────────┘ │ │
+ │ └──────────────────────┘ │ │ │
+ │ │ │ │ onError() │
+ │ │ onError() │ onError() │ │
+ │ ▼ ▼ │ │
+ │ ┌────────────────────────────────────────────────┐ │ │
+ └─────────────────────────── │ Error │ ◀┘ │
+ └────────────────────────────────────────────────┘ │
+ │ ▲ onError() │
+ │ onFatalError() └──────────────────┘
+ ▼
+ ┌──────────────────────┐
+ │ FatalError │
+ └──────────────────────┘
+
+*/
+
+
+/* Maps allowed state transitions
+ TorConnectStateTransitions[state] maps to an array of allowed states to transition to
+*/
+const TorConnectStateTransitions =
+ Object.freeze(new Map([
+ [TorConnectState.Initial,
+ [TorConnectState.Disabled,
+ TorConnectState.Bootstrapping,
+ TorConnectState.Configuring,
+ TorConnectState.Error]],
+ [TorConnectState.Configuring,
+ [TorConnectState.AutoConfiguring,
+ TorConnectState.Bootstrapping,
+ TorConnectState.Error]],
+ [TorConnectState.AutoConfiguring,
+ [TorConnectState.Configuring,
+ TorConnectState.Bootstrapping,
+ TorConnectState.Error]],
+ [TorConnectState.Bootstrapping,
+ [TorConnectState.Configuring,
+ TorConnectState.Bootstrapped,
+ TorConnectState.Error]],
+ [TorConnectState.Error,
+ [TorConnectState.Configuring,
+ TorConnectState.FatalError]],
+ // terminal states
+ [TorConnectState.FatalError, []],
+ [TorConnectState.Bootstrapped, []],
+ [TorConnectState.Disabled, []],
+ ]));
+
+/* Topics Notified by the TorConnect module */
+const TorConnectTopics = Object.freeze({
+ StateChange: "torconnect:state-change",
+ BootstrapProgress: "torconnect:bootstrap-progress",
+ BootstrapComplete: "torconnect:bootstrap-complete",
+ BootstrapError: "torconnect:bootstrap-error",
+ FatalError: "torconnect:fatal-error",
+});
+
+const TorConnect = (() => {
+ let retval = {
+
+ _state: TorConnectState.Initial,
+ _bootstrapProgress: 0,
+ _bootstrapStatus: null,
+ _errorMessage: null,
+ _errorDetails: null,
+ _logHasWarningOrError: false,
+
+ /* These functions are called after transitioning to a new state */
+ _transitionCallbacks: Object.freeze(new Map([
+ /* Initial is never transitioned to */
+ [TorConnectState.Initial, null],
+ /* Configuring */
+ [TorConnectState.Configuring, (self, prevState) => {
+ // TODO move this to the transition function
+ if (prevState === TorConnectState.Bootstrapping) {
+ TorProtocolService.torStopBootstrap();
+ }
+ }],
+ /* AutoConfiguring */
+ [TorConnectState.AutoConfiguring, (self, prevState) => {
+
+ }],
+ /* Bootstrapping */
+ [TorConnectState.Bootstrapping, (self, prevState) => {
+ let error = TorProtocolService.connect();
+ if (error) {
+ self.onError(error.message, error.details);
+ } else {
+ self._errorMessage = self._errorDetails = null;
+ }
+ }],
+ /* Bootstrapped */
+ [TorConnectState.Bootstrapped, (self,prevState) => {
+ // notify observers of bootstrap completion
+ Services.obs.notifyObservers(null, TorConnectTopics.BootstrapComplete);
+ }],
+ /* Error */
+ [TorConnectState.Error, (self, prevState, errorMessage, errorDetails, fatal) => {
+ self._errorMessage = errorMessage;
+ self._errorDetails = errorDetails;
+
+ Services.obs.notifyObservers({message: errorMessage, details: errorDetails}, TorConnectTopics.BootstrapError);
+ if (fatal) {
+ self.onFatalError();
+ } else {
+ self.beginConfigure();
+ }
+ }],
+ /* FatalError */
+ [TorConnectState.FatalError, (self, prevState) => {
+ Services.obs.notifyObservers(null, TorConnectTopics.FatalError);
+ }],
+ /* Disabled */
+ [TorConnectState.Disabled, (self, prevState) => {
+
+ }],
+ ])),
+
+ _changeState: function(newState, ...args) {
+ const prevState = this._state;
+
+ // ensure this is a valid state transition
+ if (!TorConnectStateTransitions.get(prevState)?.includes(newState)) {
+ throw Error(`TorConnect: Attempted invalid state transition from ${prevState} to ${newState}`);
+ }
+
+ console.log(`TorConnect: transitioning state from ${prevState} to ${newState}`);
+
+ // set our new state first so that state transitions can themselves trigger
+ // a state transition
+ this._state = newState;
+
+ // call our transition function and forward any args
+ this._transitionCallbacks.get(newState)(this, prevState, ...args);
+
+ Services.obs.notifyObservers({state: newState}, TorConnectTopics.StateChange);
+ },
+
+ // init should be called on app-startup in MainProcessingSingleton.jsm
+ init : function() {
+ console.log("TorConnect: Init");
+
+ // delay remaining init until after profile-after-change
+ Services.obs.addObserver(this, BrowserTopics.ProfileAfterChange);
+ },
+
+ observe: async function(subject, topic, data) {
+ console.log(`TorConnect: observed ${topic}`);
+
+ switch(topic) {
+
+ /* Determine which state to move to from Initial */
+ case BrowserTopics.ProfileAfterChange: {
+ if (TorLauncherUtil.useLegacyLauncher || !TorProtocolService.ownsTorDaemon) {
+ // Disabled
+ this.legacyOrSystemTor();
+ } else {
+ // register the Tor topics we always care about
+ for (const topicKey in TorTopics) {
+ const topic = TorTopics[topicKey];
+ Services.obs.addObserver(this, topic);
+ console.log(`TorConnect: observing topic '${topic}'`);
+ }
+
+ if (TorProtocolService.torProcessStatus == TorProcessStatus.Running) {
+ if (this.shouldQuickStart) {
+ // Quickstart
+ this.beginBootstrap();
+ } else {
+ // Configuring
+ this.beginConfigure();
+ }
+ }
+ }
+
+ Services.obs.removeObserver(this, topic);
+ break;
+ }
+ /* Transition out of Initial if Tor daemon wasn't running yet in BrowserTopics.ProfileAfterChange */
+ case TorTopics.ProcessIsReady: {
+ if (this.state === TorConnectState.Initial)
+ {
+ if (this.shouldQuickStart) {
+ // Quickstart
+ this.beginBootstrap();
+ } else {
+ // Configuring
+ this.beginConfigure();
+ }
+ }
+ break;
+ }
+ /* Updates our bootstrap status */
+ case TorTopics.BootstrapStatus: {
+ if (this._state != TorConnectState.Bootstrapping) {
+ console.log(`TorConnect: observed ${TorTopics.BootstrapStatus} topic while in state TorConnectState.${this._state}`);
+ break;
+ }
+
+ const obj = subject?.wrappedJSObject;
+ if (obj) {
+ this._bootstrapProgress= obj.PROGRESS;
+ this._bootstrapStatus = TorLauncherUtil.getLocalizedBootstrapStatus(obj, "TAG");
+
+ console.log(`TorConnect: Bootstrapping ${this._bootstrapProgress}% complete (${this._bootstrapStatus})`);
+ Services.obs.notifyObservers({
+ progress: this._bootstrapProgress,
+ status: this._bootstrapStatus,
+ hasWarnings: this._logHasWarningOrError
+ }, TorConnectTopics.BootstrapProgress);
+
+ if (this._bootstrapProgress === 100) {
+ this.bootstrapComplete();
+ }
+ }
+ break;
+ }
+ /* Handle bootstrap error*/
+ case TorTopics.BootstrapError: {
+ const obj = subject?.wrappedJSObject;
+ await TorProtocolService.torStopBootstrap();
+ this.onError(obj.message, obj.details);
+ break;
+ }
+ case TorTopics.LogHasWarnOrErr: {
+ this._logHasWarningOrError = true;
+ break;
+ }
+ default:
+ // ignore
+ break;
+ }
+ },
+
+ /*
+ Various getters
+ */
+
+ get shouldShowTorConnect() {
+ // TorBrowser must control the daemon
+ return (TorProtocolService.ownsTorDaemon &&
+ // and we're not using the legacy launcher
+ !TorLauncherUtil.useLegacyLauncher &&
+ // if we have succesfully bootstraped, then no need to show TorConnect
+ this.state != TorConnectState.Bootstrapped);
+ },
+
+ get shouldQuickStart() {
+ // quickstart must be enabled
+ return Services.prefs.getBoolPref(TorLauncherPrefs.quickstart, false) &&
+ // and the previous bootstrap attempt must have succeeded
+ !Services.prefs.getBoolPref(TorLauncherPrefs.prompt_at_startup, true);
+ },
+
+ get state() {
+ return this._state;
+ },
+
+ get bootstrapProgress() {
+ return this._bootstrapProgress;
+ },
+
+ get bootstrapStatus() {
+ return this._bootstrapStatus;
+ },
+
+ get errorMessage() {
+ return this._errorMessage;
+ },
+
+ get errorDetails() {
+ return this._errorDetails;
+ },
+
+ get logHasWarningOrError() {
+ return this._logHasWarningOrError;
+ },
+
+ /*
+ These functions tell TorConnect to transition states
+ */
+
+ legacyOrSystemTor: function() {
+ console.log("TorConnect: legacyOrSystemTor()");
+ this._changeState(TorConnectState.Disabled);
+ },
+
+ beginBootstrap: function() {
+ console.log("TorConnect: beginBootstrap()");
+ this._changeState(TorConnectState.Bootstrapping);
+ },
+
+ beginConfigure: function() {
+ console.log("TorConnect: beginConfigure()");
+ this._changeState(TorConnectState.Configuring);
+ },
+
+ autoConfigure: function() {
+ console.log("TorConnect: autoConfigure()");
+ // TODO: implement
+ throw Error("TorConnect: not implemented");
+ },
+
+ cancelAutoConfigure: function() {
+ console.log("TorConnect: cancelAutoConfigure()");
+ // TODO: implement
+ throw Error("TorConnect: not implemented");
+ },
+
+ cancelBootstrap: function() {
+ console.log("TorConnect: cancelBootstrap()");
+ this._changeState(TorConnectState.Configuring);
+ },
+
+ bootstrapComplete: function() {
+ console.log("TorConnect: bootstrapComplete()");
+ this._changeState(TorConnectState.Bootstrapped);
+ },
+
+ onError: function(message, details) {
+ console.log("TorConnect: onError()");
+ this._changeState(TorConnectState.Error, message, details, false);
+ },
+
+ onFatalError: function() {
+ console.log("TorConnect: onFatalError()");
+ // TODO: implement
+ throw Error("TorConnect: not implemented");
+ },
+
+ /*
+ Further external commands and helper methods
+ */
+ openTorPreferences: function() {
+ const win = BrowserWindowTracker.getTopWindow();
+ win.switchToTabHavingURI("about:preferences#tor", true);
+ },
+
+ openTorConnect: function() {
+ const win = BrowserWindowTracker.getTopWindow();
+ win.switchToTabHavingURI("about:torconnect", true, {ignoreQueryString: true});
+ },
+
+ copyTorLogs: function() {
+ // Copy tor log messages to the system clipboard.
+ const chSvc = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
+ Ci.nsIClipboardHelper
+ );
+ const countObj = { value: 0 };
+ chSvc.copyString(TorProtocolService.getLog(countObj));
+ const count = countObj.value;
+ return TorLauncherUtil.getFormattedLocalizedString(
+ "copiedNLogMessagesShort",
+ [count],
+ 1
+ );
+ },
+
+ // called from browser.js on browser startup, passed in either the user's homepage(s)
+ // or uris passed via command-line; we want to replace them with about:torconnect uris
+ // which redirect after bootstrapping
+ getURIsToLoad: function(uriVariant) {
+ // convert the object we get from browser.js
+ let uriStrings = ((v) => {
+ // an interop array
+ if (v instanceof Ci.nsIArray) {
+ // Transform the nsIArray of nsISupportsString's into a JS Array of
+ // JS strings.
+ return Array.from(
+ v.enumerate(Ci.nsISupportsString),
+ supportStr => supportStr.data
+ );
+ // an interop string
+ } else if (v instanceof Ci.nsISupportsString) {
+ return [v.data];
+ // a js string
+ } else if (typeof v === "string") {
+ return v.split("|");
+ // a js array of js strings
+ } else if (Array.isArray(v) &&
+ v.reduce((allStrings, entry) => {return allStrings && (typeof entry === "string");}, true)) {
+ return v;
+ }
+ // about:tor as safe fallback
+ console.log(`TorConnect: getURIsToLoad() received unknown variant '${JSON.stringify(v)}'`);
+ return ["about:tor"];
+ })(uriVariant);
+
+ // will attempt to convert user-supplied string to a uri, fallback to about:tor if cannot convert
+ // to valid uri object
+ let uriStringToUri = (uriString) => {
+ const fixupFlags = Ci.nsIURIFixup.FIXUP_FLAG_NONE;
+ let uri = Services.uriFixup.getFixupURIInfo(uriString, fixupFlags)
+ .preferredURI;
+ return uri ? uri : Services.io.newURI("about:tor");
+ };
+ let uris = uriStrings.map(uriStringToUri);
+
+ // assume we have a valid uri and generate an about:torconnect redirect uri
+ let uriToRedirectUri = (uri) => {
+ return`about:torconnect?redirect=${encodeURIComponent(uri.spec)}`;
+ };
+ let redirectUris = uris.map(uriToRedirectUri);
+
+ console.log(`TorConnect: will load after bootstrap => [${uris.map((uri) => {return uri.spec;}).join(", ")}]`);
+ return redirectUris;
+ },
+ };
+ retval.init();
+ return retval;
+})(); /* TorConnect */
diff --git a/browser/modules/TorProcessService.jsm b/browser/modules/TorProcessService.jsm
new file mode 100644
index 000000000000..201e331b2806
--- /dev/null
+++ b/browser/modules/TorProcessService.jsm
@@ -0,0 +1,12 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["TorProcessService"];
+
+var TorProcessService = {
+ get isBootstrapDone() {
+ const svc = Cc["@torproject.org/torlauncher-process-service;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+ return svc.mIsBootstrapDone;
+ },
+};
diff --git a/browser/modules/TorProtocolService.jsm b/browser/modules/TorProtocolService.jsm
index 409d6be60b83..b8678fbca9aa 100644
--- a/browser/modules/TorProtocolService.jsm
+++ b/browser/modules/TorProtocolService.jsm
@@ -1,21 +1,60 @@
+// Copyright (c) 2021, The Tor Project, Inc.
+
"use strict";
-var EXPORTED_SYMBOLS = ["TorProtocolService"];
+var EXPORTED_SYMBOLS = ["TorProtocolService", "TorProcessStatus"];
-const { TorLauncherUtil } = ChromeUtils.import(
- "resource://torlauncher/modules/tl-util.jsm"
+const { Services } = ChromeUtils.import(
+ "resource://gre/modules/Services.jsm"
);
+// see tl-process.js
+const TorProcessStatus = Object.freeze({
+ Unknown: 0,
+ Starting: 1,
+ Running: 2,
+ Exited: 3,
+});
+
+/* Browser observer topis */
+const BrowserTopics = Object.freeze({
+ ProfileAfterChange: "profile-after-change",
+});
+
var TorProtocolService = {
- _tlps: Cc["@torproject.org/torlauncher-protocol-service;1"].getService(
- Ci.nsISupports
- ).wrappedJSObject,
+ _TorLauncherUtil: function() {
+ let { TorLauncherUtil } = ChromeUtils.import(
+ "resource://torlauncher/modules/tl-util.jsm"
+ );
+ return TorLauncherUtil;
+ }(),
+ _TorLauncherProtocolService: null,
+ _TorProcessService: null,
// maintain a map of tor settings set by Tor Browser so that we don't
// repeatedly set the same key/values over and over
// this map contains string keys to primitive or array values
_settingsCache: new Map(),
+ init() {
+ Services.obs.addObserver(this, BrowserTopics.ProfileAfterChange);
+ },
+
+ observe(subject, topic, data) {
+ if (topic === BrowserTopics.ProfileAfterChange) {
+ // we have to delay init'ing this or else the crypto service inits too early without a profile
+ // which breaks the password manager
+ this._TorLauncherProtocolService = Cc["@torproject.org/torlauncher-protocol-service;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject;
+ this._TorProcessService = Cc["@torproject.org/torlauncher-process-service;1"].getService(
+ Ci.nsISupports
+ ).wrappedJSObject,
+
+ Services.obs.removeObserver(this, topic);
+ }
+ },
+
_typeof(aValue) {
switch (typeof aValue) {
case "boolean":
@@ -199,9 +238,9 @@ var TorProtocolService = {
await this.sendCommand("SAVECONF");
},
- getLog() {
- let countObj = { value: 0 };
- let torLog = this._tlps.TorGetLog(countObj);
+ getLog(countObj) {
+ countObj = countObj || { value: 0 };
+ let torLog = this._TorLauncherProtocolService.TorGetLog(countObj);
return torLog;
},
@@ -321,3 +360,4 @@ var TorProtocolService = {
return TorProcessStatus.Unknown;
},
};
+TorProtocolService.init();
\ No newline at end of file
diff --git a/browser/modules/TorStrings.jsm b/browser/modules/TorStrings.jsm
index cc4f6b340c5f..73671c08693d 100644
--- a/browser/modules/TorStrings.jsm
+++ b/browser/modules/TorStrings.jsm
@@ -261,6 +261,9 @@ var TorStrings = {
"Tor Browser routes your traffic over the Tor Network, run by thousands of volunteers around the world."
),
learnMore: getString("torPreferences.learnMore", "Learn More"),
+ quickstartHeading: getString("torPreferences.quickstart", "Quickstart"),
+ quickstartDescription: getString("torPreferences.quickstartDescription", "Quickstart allows Tor Browser to connect automatically."),
+ quickstartCheckbox : getString("torPreferences.quickstartCheckbox", "Always connect automatically"),
bridgesHeading: getString("torPreferences.bridges", "Bridges"),
bridgesDescription: getString(
"torPreferences.bridgesDescription",
@@ -368,6 +371,83 @@ var TorStrings = {
return retval;
})() /* Tor Network Settings Strings */,
+ torConnect: (() => {
+ const tsbNetwork = new TorDTDStringBundle(
+ ["chrome://torlauncher/locale/network-settings.dtd"],
+ ""
+ );
+ const tsbLauncher = new TorPropertyStringBundle(
+ "chrome://torlauncher/locale/torlauncher.properties",
+ "torlauncher."
+ );
+ const tsbCommon = new TorPropertyStringBundle(
+ "chrome://global/locale/commonDialogs.properties",
+ ""
+ );
+
+ const getStringNet = tsbNetwork.getString.bind(tsbNetwork);
+ const getStringLauncher = tsbLauncher.getString.bind(tsbLauncher);
+ const getStringCommon = tsbCommon.getString.bind(tsbCommon);
+
+ return {
+ torConnect: getStringNet(
+ "torsettings.wizard.title.default",
+ "Connect to Tor"
+ ),
+
+ torConnecting: getStringNet(
+ "torsettings.wizard.title.connecting",
+ "Establishing a Connection"
+ ),
+
+ torNotConnectedConcise: getStringNet(
+ "torConnect.notConnectedConcise",
+ "Not Connected"
+ ),
+
+ torConnectingConcise: getStringNet(
+ "torConnect.connectingConcise",
+ "Connecting…"
+ ),
+
+ torBootstrapFailed: getStringLauncher(
+ "tor_bootstrap_failed",
+ "Tor failed to establish a Tor network connection."
+ ),
+
+ torConfigure: getStringNet(
+ "torsettings.wizard.title.configure",
+ "Tor Network Settings"
+ ),
+
+ copyLog: getStringNet(
+ "torConnect.copyLog",
+ "Copy Tor Logs"
+ ),
+
+ torConnectButton: getStringNet("torSettings.connect", "Connect"),
+
+ cancel: getStringCommon("Cancel", "Cancel"),
+
+ torConnected: getStringLauncher(
+ "torlauncher.bootstrapStatus.done",
+ "Connected to the Tor network"
+ ),
+
+ torConnectedConcise: getStringLauncher(
+ "torConnect.connectedConcise",
+ "Connected"
+ ),
+
+ tryAgain: getStringNet("torConnect.tryAgain", "Try connecting again"),
+ offline: getStringNet("torConnect.offline", "Offline"),
+
+ // tor connect strings for message box in about:preferences#tor
+ connectMessage: getStringNet("torConnect.connectMessage", "Changes to Tor Settings will not take effect until you connect to the Tor Network"),
+ tryAgainMessage: getStringNet("torConnect.tryAgainMessage", "Tor Browser has failed to establish a connection to the Tor Network"),
+ };
+ })(),
+
/*
Tor Onion Services Strings, e.g., for the authentication prompt.
*/
diff --git a/browser/modules/moz.build b/browser/modules/moz.build
index 1f7c6bc4c67e..1ea57aba1a93 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -153,6 +153,8 @@ EXTRA_JS_MODULES += [
"TabsList.jsm",
"TabUnloader.jsm",
"ThemeVariableMap.jsm",
+ 'TorConnect.jsm',
+ 'TorProcessService.jsm',
"TorProtocolService.jsm",
"TorStrings.jsm",
"TransientPrefs.jsm",
diff --git a/browser/themes/shared/identity-block/identity-block.inc.css b/browser/themes/shared/identity-block/identity-block.inc.css
index a863d1d7d20e..145ea2732846 100644
--- a/browser/themes/shared/identity-block/identity-block.inc.css
+++ b/browser/themes/shared/identity-block/identity-block.inc.css
@@ -53,16 +53,15 @@
border-radius: var(--urlbar-icon-border-radius);
}
-%ifdef MOZ_OFFICIAL_BRANDING
#identity-box[pageproxystate="valid"].notSecureText #identity-icon-label,
#identity-box[pageproxystate="valid"].chromeUI #identity-icon-label {
- color: #420C5D;
+ color: var(--tor-branding-color);
+ opacity: 1;
}
toolbar[brighttext] #identity-box[pageproxystate="valid"].chromeUI #identity-icon-label {
color: #CC80FF;
}
-%endif
#identity-box[pageproxystate="valid"].chromeUI #identity-icon-label,
#identity-box[pageproxystate="valid"].extensionPage #identity-icon-label,
@@ -161,6 +160,8 @@ toolbar[brighttext] #identity-box[pageproxystate="valid"].chromeUI #identity-ico
#identity-box[pageproxystate="valid"].chromeUI #identity-icon {
list-style-image: url(chrome://branding/content/identity-icons-brand.svg);
+ fill: var(--tor-branding-color);
+ fill-opacity: 1;
}
#identity-box[pageproxystate="valid"].localResource #identity-icon {
diff --git a/browser/themes/shared/jar.inc.mn b/browser/themes/shared/jar.inc.mn
index 3b11a9864cf8..b2e469b90aa8 100644
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -9,6 +9,8 @@
skin/classic/browser/aboutNetError.css (../shared/aboutNetError.css)
skin/classic/browser/offlineSupportPages.css (../shared/offlineSupportPages.css)
+ skin/classic/browser/onionPattern.css (../shared/onionPattern.css)
+ skin/classic/browser/onionPattern.svg (../shared/onionPattern.svg)
skin/classic/browser/blockedSite.css (../shared/blockedSite.css)
skin/classic/browser/error-pages.css (../shared/error-pages.css)
skin/classic/browser/aboutRestartRequired.css (../shared/aboutRestartRequired.css)
diff --git a/browser/themes/shared/onionPattern.css b/browser/themes/shared/onionPattern.css
new file mode 100644
index 000000000000..1852350d57f7
--- /dev/null
+++ b/browser/themes/shared/onionPattern.css
@@ -0,0 +1,31 @@
+/* Onion pattern */
+
+.onion-pattern-container {
+
+ flex: auto; /* grow to consume remaining space on the page */
+ display: flex;
+ margin: 0 auto;
+ width: 100%;
+ /* two onions tall, 4x the radius */
+ height: calc(4 * var(--onion-radius));
+ max-height: calc(4 * var(--onion-radius));
+ min-height: calc(4 * var(--onion-radius));
+ direction: ltr;
+}
+
+.onion-pattern-crop {
+ height: 100%;
+ width: 100%;
+
+ -moz-context-properties: fill;
+ fill: var(--onion-color, currentColor);
+ /* opacity of the entire div, not context-opacity */
+ opacity: var(--onion-opacity, 1);
+
+ background-image: url("chrome://browser/skin/onionPattern.svg");
+ background-repeat: repeat;
+ background-attachment: local;
+ background-position: center;
+ /* svg source is 6 onions wide and 2 onions tall */
+ background-size: calc(6 * 2 * var(--onion-radius)) calc(2 * 2 * var(--onion-radius));;
+}
\ No newline at end of file
diff --git a/browser/themes/shared/onionPattern.inc.xhtml b/browser/themes/shared/onionPattern.inc.xhtml
new file mode 100644
index 000000000000..de57b6ee301a
--- /dev/null
+++ b/browser/themes/shared/onionPattern.inc.xhtml
@@ -0,0 +1,12 @@
+<!--
+ Container div that holds onionPattern.svg
+ It is expected the includer of this xhtml file also includes onionPattern.css
+ and define the following vars:
+ onion-radius : radius of an onion
+ onion-color : the base color of the onion pattern
+ onion-opacity : the opacity of the entire repeating pattern
+-->
+
+<div class="onion-pattern-container">
+ <div class="onion-pattern-crop"/>
+</div>
\ No newline at end of file
diff --git a/browser/themes/shared/onionPattern.svg b/browser/themes/shared/onionPattern.svg
new file mode 100644
index 000000000000..e2937b175341
--- /dev/null
+++ b/browser/themes/shared/onionPattern.svg
@@ -0,0 +1,22 @@
+<svg fill="context-fill" viewBox="0 0 900 300" width="900" height="300" xmlns="http://www.w3.org/2000/svg">
+ <g>
+ <path d="m825 0c41.421 0 75 33.5786 75 75 0 41.421-33.579 75-75 75z" fill-opacity=".3"/>
+ <path d="m750 0c41.421 0 75 33.5786 75 75 0 41.421-33.579 75-75 75z" fill-opacity=".15"/>
+ <path d="m525 225c0-41.421-33.579-75-75-75s-75 33.579-75 75z" fill-opacity=".3"/>
+ <path d="m525 300c0-41.421-33.579-75-75-75s-75 33.579-75 75z" fill-opacity=".15"/>
+ <path d="m300 0c0 41.4214-33.579 75-75 75s-75-33.5786-75-75z" fill-opacity=".3"/>
+ <path d="m300 75c0 41.421-33.579 75-75 75s-75-33.579-75-75z" fill-opacity=".15"/>
+ <g clip-rule="evenodd" fill-opacity=".3" fill-rule="evenodd">
+ <path d="m525 .25c-.176 0-.351.000606-.527.001817-.966.006671-1.744.795563-1.737 1.762033.006.96648.795 1.74455 1.762 1.73788.167-.00115.334-.00173.502-.00173s.335.00058.502.00173c.967.00667 1.756-.7714 1.762-1.73788.007-.96647-.771-1.755363-1.737-1.762033-.176-.001211-.351-.001817-.527-.001817zm7.849.407251c-.962-.100329-1.822.597609-1.923 1.558879-.1.96128.598 1.82188 1.559 1.92221.333.03473.665.07174.996.11103.96.11381 1.83-.57199 1.944-1.53176s-.572-1.830084-1.532-1.943891c-.347-.041214-.695-.080042-1.044-.116468zm-15.334 3.481099c.961-.10034 1.659-.96094 1.559-1.92221-.101-.96128-.961-1.659216-1.923-1.558886-.349.036426-.697.075254-1.044.116468-.96.113808-1.646.984118-1.532 1.943888.114.95978.984 1.64557 1.944 1.53176.331-.03928.663-.0763.996-.11102zm23.612-2.14381c-.944-.2076-1.877.38933-2.085 1.33327-.207.94394.389 1.87744 1.333 2.08504.326.07165.651.14553.975.22162.941.2209 1.883-.36277 2.104-1.30369.221-.94091-.363-1.88275-1.304-2.10366-.34-.07986-.681-.15739-1.
023-.23258zm-31.502 3.41832c.944-.2076 1.54-1.14111 1.333-2.08505-.208-.94394-1.141-1.54086-2.085-1.33326-.342.07519-.683.15272-1.023.23257-.941.22091-1.525 1.16276-1.304 2.10367s1.163 1.52459 2.104 1.30368c.324-.07609.649-.14997.975-.22161zm39.576-1.15763c-.914-.31276-1.909.17503-2.222 1.08953-.312.91449.175 1.90938 1.09 2.22214.315.10775.629.21764.942.32966.91.32565 1.912-.14805 2.237-1.05804.326-.90998-.148-1.91166-1.058-2.23731-.328-.11756-.658-.2329-.989-.34598zm-47.27 3.31168c.915-.31277 1.402-1.30766 1.09-2.22215-.313-.91449-1.308-1.40229-2.222-1.08952-.331.11308-.661.22841-.989.34598-.91.32565-1.384 1.32733-1.058 2.23731.325.90999 1.327 1.38369 2.237 1.05804.313-.11202.627-.22191.942-.32966zm55.037-.15521c-.874-.41383-1.917-.04125-2.331.83218-.414.87342-.041 1.91692.832 2.33072.301.1427.601.2875.9.4343.868.426 1.916.0682 2.343-.7993.426-.86751.068-1.91617-.8-2.34226-.313-.15402-.628-.3059-.944-.45564zm-62.437 3.163c.873-.4139 1.246-1.45739.832-2.33082-.414-.87342-1.457-1.246
-2.331-.83217-.316.14973-.631.30162-.944.45564-.868.42608-1.226 1.47475-.8 2.34225s1.475 1.2254 2.343.7993c.298-.1468.599-.2916.9-.4342zm69.8.8472c-.822-.5092-1.901-.2561-2.41.5653-.509.8215-.256 1.9002.565 2.4095.284.1756.566.3532.846.5327.815.5207 1.897.2827 2.418-.5315.52-.8143.282-1.8965-.532-2.4172-.294-.1883-.59-.3746-.887-.5588zm-76.817 2.9748c.821-.5092 1.074-1.588.565-2.4095-.509-.8214-1.588-1.0745-2.41-.5653-.297.1843-.593.3705-.887.5588-.814.5207-1.052 1.6029-.532 2.4172.521.8142 1.603 1.0522 2.418.5315.28-.1795.562-.3571.846-.5327zm83.683 1.834c-.759-.5978-1.859-.4668-2.457.2927-.598.7594-.467 1.8597.292 2.4575.262.206.523.4139.781.6235.751.6084 1.853.4927 2.462-.2583.608-.7511.492-1.8531-.259-2.4614-.271-.2199-.544-.4379-.819-.654zm-90.229 2.7502c.759-.5978.89-1.6981.292-2.4575-.598-.7595-1.698-.8905-2.457-.2927-.275.2161-.548.4341-.819.654-.751.6083-.867 1.7103-.259 2.4614.609.751 1.711.8667 2.462.2583.258-.2096.519-.4175.781-.6235zm96.516 2.7935c-.688-.6786-1.796-.670
9-2.475.0173-.678.6881-.67 1.7962.018 2.4748.237.2339.473.4695.706.7067.679.6882 1.787.6959 2.475.0173s.696-1.7867.018-2.4748c-.246-.2488-.493-.4959-.742-.7413zm-102.511 2.4921c.688-.6786.696-1.7866.017-2.4748-.678-.6882-1.786-.6959-2.474-.0173-.249.2454-.496.4925-.742.7413-.678.6881-.67 1.7962.018 2.4748s1.796.6709 2.474-.0173c.234-.2372.47-.4728.707-.7067zm108.142 3.7171c-.608-.751-1.71-.8667-2.461-.2583-.751.6083-.867 1.7103-.258 2.4613.209.2588.417.5191.623.7809.598.7595 1.698.8905 2.458.2927.759-.5978.89-1.698.292-2.4575-.216-.2746-.434-.5476-.654-.8191zm-113.511 2.203c.609-.751.493-1.853-.258-2.4613-.751-.6084-1.853-.4927-2.461.2583-.22.2715-.438.5445-.654.8191-.598.7595-.467 1.8598.292 2.4575.76.5978 1.86.4668 2.458-.2927.206-.2618.414-.5221.623-.7809zm118.415 4.5953c-.52-.8142-1.603-1.0522-2.417-.5315s-1.052 1.6029-.531 2.4171c.179.2807.357.5627.532.8461.51.8214 1.588 1.0745 2.41.5653.821-.5092 1.074-1.588.565-2.4094-.184-.2973-.37-.5931-.559-.8876zm-123.09 1.8856c.521-.8142
.283-1.8964-.531-2.4171s-1.897-.2827-2.417.5315c-.189.2945-.375.5903-.559.8876-.509.8215-.256 1.9002.565 2.4094.822.5093 1.9.2561 2.41-.5653.175-.2834.353-.5654.532-.8461zm127.204 5.4202c-.426-.8675-1.475-1.2254-2.343-.7993-.867.4261-1.225 1.4748-.799 2.3423.147.2988.292.5988.434.9.414.8734 1.458 1.246 2.331.8322.874-.4139 1.246-1.4574.832-2.3308-.149-.3161-.301-.6309-.455-.9444zm-131.124 1.543c.426-.8675.068-1.9162-.799-2.3423-.868-.4261-1.917-.0682-2.343.7993-.154.3135-.306.6284-.455.9444-.414.8734-.042 1.9169.832 2.3308.873.4138 1.917.0412 2.331-.8322.142-.3012.287-.6012.434-.9zm134.39 6.1791c-.326-.91-1.328-1.3837-2.238-1.0581-.91.3257-1.383 1.3273-1.058 2.2373.112.3131.222.6271.33.9421.313.9145 1.308 1.4023 2.222 1.0896.915-.3128 1.403-1.3077 1.09-2.2222-.113-.3306-.229-.6602-.346-.9887zm-137.502 1.1793c.325-.91-.148-1.9117-1.058-2.2374-.91-.3256-1.912.1481-2.238 1.0581-.117.3285-.233.6581-.346.9887-.313.9145.175 1.9094 1.09 2.2222.914.3127 1.909-.1751 2.222-1.0895.108-.3151.21
8-.6291.33-.9421zm139.876 6.8607c-.221-.9409-1.163-1.5246-2.104-1.3037s-1.524 1.1628-1.303 2.1037c.076.3241.15.649.221.9748.208.9439 1.141 1.5408 2.085 1.3332s1.541-1.1411 1.333-2.085c-.075-.3419-.152-.6829-.232-1.023zm-142.139.8c.221-.9409-.362-1.8828-1.303-2.1037s-1.883.3628-2.104 1.3037c-.08.3401-.157.6811-.232 1.023-.208.944.389 1.8775 1.333 2.0851s1.877-.3894 2.085-1.3333c.071-.3258.145-.6507.221-.9748zm143.592 7.4568c-.114-.9598-.984-1.6456-1.944-1.5318-.959.1138-1.645.9841-1.531 1.9439.039.3313.076.6634.111.9961.1.9612.961 1.6592 1.922 1.5588.961-.1003 1.659-.9609 1.559-1.9222-.037-.349-.076-.6973-.117-1.0448zm-144.977.4121c.114-.9597-.572-1.8301-1.531-1.9439-.96-.1138-1.83.572-1.944 1.5318-.041.3476-.08.6959-.117 1.0449-.1.9612.598 1.8218 1.559 1.9222.961.1003 1.822-.5976 1.922-1.5589.035-.3327.072-.6647.111-.9961zm145.499 7.9547c-.006-.9665-.795-1.7445-1.762-1.7379-.966.0067-1.744.7956-1.738 1.7621.001.0523.001.1046.001.1569l.001.0826v.2629c0 .1676-.001.3351-.002.5024-.006.
9665.772 1.7554 1.738 1.762.967.0067 1.756-.7714 1.762-1.7378.001-.1754.002-.3509.002-.5266s-.001-.3512-.002-.5266zm-145.996.0242c.006-.9665-.772-1.7554-1.738-1.762-.967-.0067-1.756.7714-1.762 1.7378-.001.1754-.002.3509-.002.5266s.001.3512.002.5266c.006.9665.795 1.7445 1.762 1.7379.966-.0067 1.744-.7956 1.738-1.7621-.001-.1673-.002-.3348-.002-.5024s.001-.3351.002-.5024zm145.591 8.3509c.1-.9612-.598-1.8218-1.559-1.9222-.961-.1003-1.822.5976-1.922 1.5589-.035.3327-.072.6647-.111.9961-.114.9597.572 1.83 1.531 1.9439.96.1138 1.83-.572 1.944-1.5318.042-.3476.08-.6959.117-1.0449zm-145.205-.3633c-.1-.9612-.961-1.6592-1.922-1.5588-.961.1003-1.659.9609-1.559 1.9222.037.349.076.6973.117 1.0448.114.9598.984 1.6456 1.944 1.5318.959-.1138 1.645-.9841 1.531-1.9439-.039-.3313-.076-.6634-.111-.9961zm143.867 8.642c.208-.944-.389-1.8775-1.333-2.0851s-1.877.3894-2.085 1.3333c-.071.3258-.145.6507-.221.9748-.221.9409.362 1.8828 1.303 2.1037s1.883-.3628 2.104-1.3037c.08-.3401.157-.6811.232-1.023zm-142.59
2-.7518c-.208-.9439-1.141-1.5408-2.085-1.3332s-1.541 1.1411-1.333 2.085c.075.3419.152.6829.232 1.023.221.9409 1.163 1.5246 2.104 1.3037s1.524-1.1628 1.303-2.1037c-.076-.3241-.149-.649-.221-.9748zm140.332 8.8261c.313-.9145-.175-1.9094-1.09-2.2222-.914-.3127-1.909.1751-2.222 1.0895-.108.3151-.218.6291-.33.9421-.325.91.148 1.9121 1.058 2.2371.91.326 1.912-.148 2.238-1.058.117-.3283.233-.6579.346-.9885zm-138.178-1.1326c-.313-.9145-1.308-1.4023-2.222-1.0896-.915.3128-1.403 1.3077-1.09 2.2222.113.3306.229.6602.346.9885.326.91 1.328 1.384 2.238 1.058.91-.325 1.383-1.327 1.058-2.237-.112-.3131-.222-.6271-.33-.9421zm135.021 8.8991c.414-.874.042-1.917-.832-2.331-.873-.414-1.917-.041-2.331.832-.142.301-.287.601-.434.9-.426.868-.068 1.916.799 2.343.868.426 1.917.068 2.343-.8.154-.313.306-.628.455-.944zm-132.013-1.499c-.414-.873-1.458-1.246-2.331-.832-.874.414-1.246 1.457-.832 2.331.149.316.301.631.455.944.426.868 1.475 1.226 2.343.8.867-.426 1.225-1.475.799-2.343-.147-.298-.292-.599-.434-.9zm12
8.003 8.862c.509-.822.256-1.901-.565-2.41-.822-.509-1.9-.256-2.41.565-.175.284-.353.566-.532.846-.521.815-.283 1.897.531 2.418.814.52 1.897.282 2.417-.532.189-.294.375-.59.559-.887zm-124.181-1.845c-.51-.821-1.588-1.074-2.41-.565-.821.509-1.074 1.588-.565 2.41.184.297.37.593.559.887.52.814 1.603 1.052 2.417.532.814-.521 1.052-1.603.531-2.418-.179-.28-.357-.562-.532-.846zm119.372 8.711c.598-.759.467-1.859-.292-2.457-.76-.598-1.86-.467-2.458.292-.206.262-.414.523-.623.781-.609.751-.493 1.853.258 2.462.751.608 1.853.492 2.461-.259.22-.271.438-.544.654-.819zm-114.788-2.165c-.598-.759-1.698-.89-2.458-.292-.759.598-.89 1.698-.292 2.457.216.275.434.548.654.819.608.751 1.71.867 2.461.259.751-.609.867-1.711.258-2.462-.209-.258-.417-.519-.623-.781zm109.245 8.452c.678-.688.67-1.796-.018-2.475-.688-.678-1.796-.67-2.474.018-.234.237-.47.473-.707.706-.688.679-.696 1.787-.017 2.475.678.688 1.786.696 2.474.018.249-.246.496-.493.742-.742zm-103.959-2.457c-.679-.688-1.787-.696-2.475-.017-.688.678-.696
1.786-.018 2.474.246.249.493.496.742.742.688.678 1.796.67 2.474-.018.679-.688.671-1.796-.017-2.474-.237-.234-.473-.47-.706-.707zm5.92 5.369c-.751-.609-1.853-.493-2.462.258-.608.751-.492 1.853.259 2.461.271.22.544.438.819.654.759.598 1.859.467 2.457-.292.598-.76.467-1.86-.292-2.458-.262-.206-.523-.414-.781-.623zm91.829 2.719c.751-.608.867-1.71.259-2.461-.609-.751-1.711-.867-2.462-.258-.258.209-.519.417-.781.623-.759.598-.89 1.698-.292 2.458.598.759 1.698.89 2.457.292.275-.216.548-.434.819-.654zm-6.798 4.904c.814-.52 1.052-1.603.532-2.417-.521-.814-1.603-1.052-2.418-.531-.28.179-.562.357-.846.532-.821.51-1.074 1.588-.565 2.41.509.821 1.588 1.074 2.41.565.297-.184.593-.37.887-.559zm-78.55-2.948c-.815-.521-1.897-.283-2.418.531-.52.814-.282 1.897.532 2.417.294.189.59.375.887.559.822.509 1.901.256 2.41-.565.509-.822.256-1.9-.565-2.41-.284-.175-.566-.353-.846-.532zm6.963 3.92c-.868-.426-1.916-.068-2.343.799-.426.868-.068 1.917.8 2.343.313.154.628.306.944.455.874.414 1.917.042 2.331-.832.41
4-.873.041-1.917-.832-2.331-.301-.142-.601-.287-.9-.434zm64.281 3.142c.868-.426 1.226-1.475.8-2.343-.426-.867-1.475-1.225-2.343-.799-.298.147-.599.292-.9.434-.873.414-1.246 1.458-.832 2.331.414.874 1.457 1.246 2.331.832.316-.149.631-.301.944-.455zm-7.722 3.266c.91-.326 1.384-1.328 1.058-2.238-.325-.91-1.327-1.383-2.237-1.058-.313.112-.627.222-.942.33-.915.313-1.402 1.308-1.09 2.222.313.915 1.308 1.403 2.222 1.09.331-.113.661-.229.989-.346zm-49.201-3.296c-.91-.325-1.912.148-2.237 1.058-.326.91.148 1.912 1.058 2.238.328.117.658.233.989.346.914.313 1.909-.175 2.222-1.09.312-.914-.175-1.909-1.09-2.222-.315-.108-.629-.218-.942-.33zm41.161 5.67c.941-.221 1.525-1.163 1.304-2.104s-1.163-1.524-2.104-1.303c-.324.076-.649.15-.975.221-.944.208-1.54 1.141-1.333 2.085.208.944 1.141 1.541 2.085 1.333.342-.075.683-.152 1.023-.232zm-33.5-3.407c-.941-.221-1.883.362-2.104 1.303s.363 1.883 1.304 2.104c.34.08.681.157 1.023.232.944.208 1.877-.389 2.085-1.333.207-.944-.389-1.877-1.333-2.085-.326-.071-.651
-.145-.975-.221zm7.869 1.385c-.96-.114-1.83.572-1.944 1.531-.114.96.572 1.83 1.532 1.944.347.042.695.08 1.044.117.962.1 1.822-.598 1.923-1.559.1-.961-.598-1.822-1.559-1.922-.333-.035-.665-.072-.996-.111zm17.374 3.475c.96-.114 1.646-.984 1.532-1.944-.114-.959-.984-1.645-1.944-1.531-.331.039-.663.076-.996.111-.961.1-1.659.961-1.559 1.922.101.961.961 1.659 1.923 1.559.349-.037.697-.076 1.044-.117zm-9.395-2.978c-.967-.006-1.756.772-1.762 1.738-.007.967.771 1.756 1.737 1.762.176.001.351.002.527.002s.351-.001.527-.002c.966-.006 1.744-.795 1.737-1.762-.006-.966-.795-1.744-1.762-1.738-.167.001-.334.002-.502.002-.093 0-.185 0-.278-.001-.045 0-.089 0-.134 0-.03 0-.06-.001-.09-.001zm.502-130.998c-.179 0-.357.0008-.536.0024-.966.0084-1.743.7988-1.734 1.7653.008.9664.799 1.743 1.765 1.7345.168-.0015.337-.0022.505-.0022s.337.0007.505.0022c.966.0085 1.757-.7681 1.765-1.7345.009-.9665-.768-1.7569-1.734-1.7653-.179-.0016-.357-.0024-.536-.0024zm-7.515 3.9974c.958-.1279 1.631-1.0081 1.503-1.9661s-1.00
8-1.631-1.966-1.5031c-.352.047-.703.097-1.053.1501-.956.1449-1.613 1.037-1.468 1.9926s1.037 1.6127 1.993 1.4678c.329-.0499.66-.0971.991-.1413zm15.493-3.4692c-.958-.1279-1.838.5451-1.966 1.5031s.545 1.8382 1.503 1.9661c.331.0442.662.0914.991.1413.956.1449 1.848-.5122 1.993-1.4678s-.512-1.8477-1.468-1.9926c-.35-.0531-.701-.1031-1.053-.1501zm-23.35 5.0976c.929-.2635 1.47-1.231 1.206-2.1609-.264-.9298-1.231-1.47-2.161-1.2064-.342.097-.683.1969-1.023.2998-.925.2803-1.447 1.2573-1.167 2.1823s1.257 1.4476 2.182 1.1674c.32-.0968.641-.1909.963-.2822zm31.699-3.3673c-.93-.2636-1.897.2766-2.161 1.2064-.264.9299.277 1.8974 1.206 2.1609.322.0913.643.1854.963.2822.925.2802 1.902-.2424 2.182-1.1674s-.242-1.902-1.167-2.1823c-.34-.1029-.681-.2028-1.023-.2998zm-39.242 6.1049c.882-.3942 1.278-1.4291.884-2.3116s-1.429-1.2783-2.311-.8842c-.325.1451-.648.293-.97.4436-.875.4099-1.253 1.4518-.843 2.3271.41.8752 1.452 1.2525 2.327.8426.303-.1418.607-.281.913-.4175zm47.257-3.1958c-.882-.3941-1.917.0017-2.311.
8842s.002 1.9174.884 2.3116c.306.1365.61.2757.913.4175.875.4099 1.917.0326 2.327-.8426.41-.8753.032-1.9172-.843-2.3271-.322-.1506-.645-.2985-.97-.4436zm7.516 4.0254c-.817-.516-1.898-.2718-2.414.5454s-.271 1.898.546 2.4141c.283.1787.564.3599.844.5436.808.5305 1.893.3056 2.423-.5022.531-.8079.306-1.8929-.502-2.4234-.297-.1951-.596-.3876-.897-.5775zm-61.848 2.9595c.817-.5161 1.062-1.5969.546-2.4141s-1.597-1.0614-2.414-.5454c-.301.1899-.6.3824-.897.5775-.808.5305-1.033 1.6155-.502 2.4234.53.8079 1.615 1.0327 2.423.5022.28-.1837.561-.3649.844-.5436zm68.714 2.0935c-.735-.6268-1.84-.5384-2.467.1974-.626.7357-.538 1.8402.198 2.467.255.2171.508.4364.759.658.724.6397 1.83.5709 2.47-.1536.639-.7245.571-1.8304-.154-2.4701-.266-.2353-.535-.4682-.806-.6987zm-75.179 2.6644c.736-.6268.824-1.7313.198-2.467-.627-.7358-1.732-.8242-2.467-.1974-.271.2305-.54.4634-.806.6987-.725.6397-.793 1.7456-.154 2.4701.64.7245 1.746.7933 2.47.1536.251-.2216.504-.4409.759-.658zm81.26 3.3095c-.639-.7245-1.745-.7933-2.
47-.1536-.724.6397-.793 1.7456-.153 2.4701.221.2509.441.5039.658.7587.626.7358 1.731.8242 2.467.1975.735-.6268.824-1.7313.197-2.467-.231-.2707-.463-.5393-.699-.8057zm-86.987 2.3165c.64-.7245.571-1.8304-.153-2.4701-.725-.6397-1.831-.5709-2.47.1536-.236.2664-.468.535-.699.8057-.627.7357-.538 1.8402.197 2.467.736.6267 1.841.5383 2.467-.1975.217-.2548.437-.5078.658-.7587zm92.162 4.4585c-.531-.8079-1.616-1.0327-2.424-.5022s-1.033 1.6155-.502 2.4234c.184.2796.365.5611.544.8442.516.8172 1.596 1.0614 2.414.5453.817-.516 1.061-1.5968.545-2.414-.19-.3007-.382-.5996-.577-.8967zm-97.034 1.9212c.531-.8079.306-1.8929-.502-2.4234s-1.893-.3057-2.424.5022c-.195.2971-.387.596-.577.8967-.516.8172-.272 1.898.545 2.414.818.5161 1.898.2719 2.414-.5453.179-.2831.36-.5646.544-.8442zm-3.915 7.0062c.41-.8753.033-1.9171-.843-2.3271-.875-.4099-1.917-.0326-2.327.8427-.15.3217-.298.6449-.443.9697-.395.8825.001 1.9174.884 2.3116.882.3941 1.917-.0018 2.311-.8842.137-.3057.276-.61.418-.9127zm105.108-1.4844c-.41-.87
53-1.452-1.2526-2.327-.8427-.876.41-1.253 1.4518-.843 2.3271.142.3027.281.607.418.9127.394.8824 1.429 1.2783 2.311.8842.883-.3942 1.279-1.4291.884-2.3116-.145-.3248-.293-.648-.443-.9697zm-107.981 8.9773c.28-.925-.242-1.902-1.167-2.1822-.925-.2803-1.902.2424-2.183 1.1674-.103.3396-.203.6805-.3 1.0227-.263.9299.277 1.8973 1.207 2.1609s1.897-.2766 2.161-1.2064c.091-.322.185-.6428.282-.9624zm111.034-1.0148c-.281-.925-1.258-1.4477-2.183-1.1674-.925.2802-1.447 1.2572-1.167 2.1822.097.3196.191.6404.282.9624.264.9298 1.231 1.47 2.161 1.2064s1.47-1.231 1.207-2.1609c-.097-.3422-.197-.6831-.3-1.0227zm-112.803 8.8434c.145-.9556-.513-1.8477-1.468-1.9926-.956-.1449-1.848.5122-1.993 1.4678-.053.3501-.103.7012-.15 1.0532-.128.958.545 1.8383 1.503 1.9661.958.1279 1.839-.5451 1.966-1.5031.045-.3314.092-.6619.142-.9914zm114.683-.5248c-.145-.9556-1.037-1.6127-1.993-1.4678-.955.1449-1.613 1.037-1.468 1.9926.05.3295.097.66.142.9914.127.958 1.008 1.631 1.966 1.5031.958-.1278 1.631-1.0081 1.503-1.9661-.047
-.352-.097-.7031-.15-1.0532zm-115.32 8.5262c.009-.9665-.768-1.7568-1.734-1.7653-.967-.0085-1.757.7681-1.766 1.7346-.001.1783-.002.3568-.002.5355s.001.3572.002.5355c.009.9665.799 1.7431 1.766 1.7346.966-.0085 1.743-.7989 1.734-1.7653-.001-.1681-.002-.3364-.002-.5048s.001-.3367.002-.5048zm115.996-.0307c-.009-.9665-.799-1.7431-1.766-1.7346-.966.0085-1.743.7989-1.734 1.7653.001.1016.001.2033.002.305v.1998c0 .1684-.001.3367-.002.5048-.009.9665.768 1.7568 1.734 1.7653.967.0085 1.757-.7681 1.766-1.7346.001-.1783.002-.3568.002-.5355s-.001-.3572-.002-.5355zm-115.501 8.0503c-.127-.958-1.008-1.631-1.966-1.5031-.958.1278-1.631 1.0081-1.503 1.9661.047.352.097.7031.15 1.0532.145.9555 1.037 1.6127 1.993 1.4678.955-.1449 1.613-1.037 1.468-1.9926-.05-.3295-.097-.66-.142-.9914zm114.975.463c.128-.958-.545-1.8383-1.503-1.9661-.958-.1279-1.839.5451-1.966 1.5031-.045.3314-.092.6619-.142.9914-.145.9556.513 1.8477 1.468 1.9926.956.1449 1.848-.5122 1.993-1.4678.053-.3501.103-.7012.15-1.0532zm-113.346 7.3946
c-.264-.9298-1.231-1.47-2.161-1.2064s-1.47 1.231-1.207 2.1609c.097.3422.197.6831.3 1.0227.281.925 1.258 1.4477 2.183 1.1674.925-.2802 1.447-1.2572 1.167-2.1822-.097-.3196-.191-.6404-.282-.9624zm111.616.9545c.263-.9299-.277-1.8973-1.207-2.1609s-1.897.2766-2.161 1.2064c-.091.322-.185.6428-.282.9624-.28.925.242 1.902 1.167 2.1822.925.2803 1.902-.2424 2.183-1.1674.103-.3396.203-.6805.3-1.0227zm-108.879 6.5881c-.394-.8824-1.429-1.2783-2.311-.8842-.883.3942-1.279 1.4291-.884 2.3116.145.3248.293.648.443.9696.41.875 1.452 1.253 2.327.843.876-.41 1.253-1.452.843-2.3273-.142-.3027-.281-.607-.418-.9127zm105.969 1.4274c.395-.8825-.001-1.9174-.884-2.3116-.882-.3941-1.917.0018-2.311.8842-.137.3057-.276.61-.418.9127-.41.8753-.033 1.9173.843 2.3273.875.41 1.917.032 2.327-.843.15-.3216.298-.6448.443-.9696zm-102.18 5.6476c-.516-.817-1.596-1.062-2.414-.546-.817.516-1.061 1.597-.545 2.414.19.301.382.6.577.897.531.808 1.616 1.033 2.424.502.808-.53 1.033-1.615.502-2.423-.184-.28-.365-.561-.544-.844zm98.1
55 1.868c.516-.817.272-1.898-.545-2.414-.818-.516-1.898-.271-2.414.546-.179.283-.36.564-.544.844-.531.808-.306 1.893.502 2.423.808.531 1.893.306 2.424-.502.195-.297.387-.596.577-.897zm-93.397 4.597c-.626-.736-1.731-.824-2.467-.198-.735.627-.824 1.732-.197 2.467.231.271.463.54.699.806.639.725 1.745.793 2.47.154.724-.64.793-1.746.153-2.47-.221-.251-.441-.504-.658-.759zm88.344 2.269c.627-.735.538-1.84-.197-2.467-.736-.626-1.841-.538-2.467.198-.217.255-.437.508-.658.759-.64.724-.571 1.83.153 2.47.725.639 1.831.571 2.47-.154.236-.266.468-.535.699-.806zm-5.974 6.081c.725-.639.793-1.745.154-2.47-.64-.724-1.746-.793-2.47-.153-.251.221-.504.441-.759.658-.736.626-.824 1.731-.198 2.467.627.735 1.732.824 2.467.197.271-.231.54-.463.806-.699zm-76.744-2.623c-.724-.64-1.83-.571-2.47.153-.639.725-.571 1.831.154 2.47.266.236.535.468.806.699.735.627 1.84.538 2.467-.197.626-.736.538-1.841-.198-2.467-.255-.217-.508-.437-.759-.658zm6.38 4.872c-.808-.531-1.893-.306-2.423.502-.531.808-.306 1.893.502 2.424.
297.195.596.387.897.577.817.516 1.898.272 2.414-.545.516-.818.271-1.898-.546-2.414-.283-.179-.564-.36-.844-.544zm63.589 2.926c.808-.531 1.033-1.616.502-2.424-.53-.808-1.615-1.033-2.423-.502-.28.184-.561.365-.844.544-.817.516-1.062 1.596-.546 2.414.516.817 1.597 1.061 2.414.545.301-.19.6-.382.897-.577zm-56.583.989c-.875-.41-1.917-.033-2.327.843-.41.875-.032 1.917.843 2.327.322.15.645.298.97.443.882.395 1.917-.001 2.311-.884.394-.882-.002-1.917-.884-2.311-.306-.137-.61-.276-.913-.418zm49.14 3.17c.875-.41 1.253-1.452.843-2.327-.41-.876-1.452-1.253-2.327-.843-.303.142-.607.281-.913.418-.882.394-1.278 1.429-.884 2.311.394.883 1.429 1.279 2.311.884.325-.145.648-.293.97-.443zm-41.647-.297c-.925-.28-1.902.242-2.182 1.167s.242 1.902 1.167 2.183c.34.103.681.203 1.023.3.93.263 1.897-.277 2.161-1.207s-.277-1.897-1.206-2.161c-.322-.091-.643-.185-.963-.282zm33.685 3.35c.925-.281 1.447-1.258 1.167-2.183s-1.257-1.447-2.182-1.167c-.32.097-.641.191-.963.282-.929.264-1.47 1.231-1.206 2.161s1.231 1.47
2.161 1.207c.342-.097.683-.197 1.023-.3zm-25.856-1.581c-.956-.145-1.848.513-1.993 1.468-.145.956.512 1.848 1.468 1.993.35.053.701.103 1.053.15.958.128 1.838-.545 1.966-1.503s-.545-1.839-1.503-1.966c-.331-.045-.662-.092-.991-.142zm17.537 3.461c.956-.145 1.613-1.037 1.468-1.993-.145-.955-1.037-1.613-1.993-1.468-.329.05-.66.097-.991.142-.958.127-1.631 1.008-1.503 1.966s1.008 1.631 1.966 1.503c.352-.047.703-.097 1.053-.15zm-9.536-2.824c-.966-.009-1.757.768-1.765 1.734-.009.967.768 1.757 1.734 1.766h.102l.16.001c.091.001.183.001.274.001.112 0 .225 0 .337-.001h.091l.108-.001c.966-.009 1.743-.799 1.734-1.766-.008-.966-.799-1.743-1.765-1.734-.168.001-.337.002-.505.002-.064 0-.128 0-.192 0-.104-.001-.209-.001-.313-.002zm-.022-98.9948c.176-.0021.351-.0032.527-.0032s.351.0011.527.0032c.966.0117 1.74.8046 1.728 1.771-.011.9664-.804 1.7404-1.771 1.7287-.161-.0019-.322-.0029-.484-.0029s-.323.001-.484.0029c-.967.0117-1.76-.7623-1.771-1.7287-.012-.9664.762-1.7593 1.728-1.771zm-5.261 2.1143c.176.950
4-.452 1.8634-1.402 2.0392-.316.0585-.63.1208-.944.1868-.945.1992-1.874-.4059-2.073-1.3517-.199-.9457.406-1.8739 1.352-2.0731.341-.072.684-.1398 1.028-.2035.951-.1759 1.864.4519 2.039 1.4023zm11.576 0c.175-.9504 1.088-1.5782 2.039-1.4023.344.0637.687.1315 1.028.2035.946.1992 1.551 1.1274 1.352 2.0731-.199.9458-1.128 1.5509-2.073 1.3517-.313-.066-.628-.1283-.944-.1868-.95-.1758-1.578-1.0888-1.402-2.0392zm-19.392 1.9036c.359.8973-.077 1.9158-.974 2.275-.299.1193-.595.2423-.89.3687-.888.3812-1.917-.0298-2.298-.9179s.03-1.9171.918-2.2984c.321-.1377.644-.2717.969-.4018.897-.3591 1.916.0771 2.275.9744zm27.208 0c.359-.8973 1.378-1.3335 2.275-.9744.325.1301.648.2641.969.4018.888.3813 1.299 1.4103.918 2.2984-.381.8882-1.41 1.2991-2.298.9179-.295-.1264-.591-.2494-.89-.3687-.897-.3592-1.333-1.3777-.974-2.275zm-34.499 3.4018c.528.8097.3 1.8939-.51 2.4217-.269.1754-.536.3541-.8.5359-.797.5475-1.886.3456-2.434-.4508-.547-.7965-.346-1.886.451-2.4335.288-.198.579-.3926.872-.5836.809-.5278 1.894-.29
93 2.421.5103zm41.79 0c.527-.8096 1.612-1.0381 2.421-.5103.293.1911.584.3856.872.5836.797.5475.998 1.637.451 2.4335-.548.7964-1.637.9983-2.434.4508-.264-.1818-.531-.3604-.8-.5359-.81-.5278-1.038-1.612-.51-2.4217zm-48.276 4.7598c.675.6917.662 1.7997-.03 2.4747-.23.2244-.457.4515-.682.6814-.675.6917-1.783.7052-2.474.0302-.692-.675-.705-1.783-.03-2.4747.244-.2502.491-.4975.741-.7417.692-.6751 1.8-.6616 2.475.0301zm54.762 0c.675-.6917 1.783-.7052 2.475-.0301.25.2442.497.4915.741.7417.675.6917.662 1.7997-.03 2.4747-.691.6751-1.799.6615-2.474-.0302-.225-.2299-.452-.457-.682-.6814-.692-.675-.705-1.7829-.03-2.4747zm-60.201 5.9284c.796.5475.998 1.637.451 2.4335-.182.2645-.361.5313-.536.8004-.528.8097-1.612 1.0382-2.422.5104s-1.038-1.6121-.51-2.4217c.191-.2931.385-.5837.583-.8717.548-.7965 1.637-.9984 2.434-.4509zm65.64 0c.797-.5475 1.886-.3456 2.434.4509.198.288.392.5786.583.8717.528.8097.3 1.8939-.51 2.4217s-1.894.2993-2.422-.5103c-.175-.2692-.354-.536-.536-.8005-.547-.7965-.345-1.886.451-2
.4335zm-69.823 6.873c.888.3812 1.299 1.4102.918 2.2984-.127.2945-.25.5909-.369.8891-.359.8972-1.378 1.3335-2.275.9743s-1.333-1.3777-.974-2.275c.13-.325.264-.648.402-.9689.381-.8882 1.41-1.2991 2.298-.9179zm74.006 0c.888-.3812 1.917.0297 2.298.9179.138.3209.272.6439.402.9689.359.8973-.077 1.9158-.974 2.275s-1.916-.0771-2.275-.9743c-.119-.2982-.242-.5946-.369-.8891-.381-.8882.03-1.9172.918-2.2984zm-76.761 7.559c.946.1992 1.551 1.1274 1.351 2.0732-.066.3132-.128.6278-.186.9438-.176.9504-1.089 1.5782-2.04 1.4023-.95-.1759-1.578-1.0889-1.402-2.0392.064-.3443.132-.6871.204-1.0285.199-.9457 1.127-1.5509 2.073-1.3516zm79.516 0c.946-.1993 1.874.4059 2.073 1.3516.072.3414.14.6842.204 1.0285.176.9503-.452 1.8633-1.402 2.0392-.951.1759-1.864-.4519-2.04-1.4023-.058-.316-.12-.6306-.186-.9438-.2-.9458.405-1.874 1.351-2.0732zm-80.734 7.9517c.967.0116 1.741.8045 1.729 1.771-.002.1611-.003.3225-.003.4842s.001.3231.003.4842c.012.9665-.762 1.7594-1.729 1.771-.966.0117-1.759-.7622-1.771-1.7287-.002-.175
2-.003-.3507-.003-.5265s.001-.3513.003-.5265c.012-.9665.805-1.7404 1.771-1.7287zm81.952 0c.966-.0117 1.759.7622 1.771 1.7287.001.0705.001.1411.002.2117.001.1048.001.2098.001.3148 0 .1318-.001.2635-.002.395l-.001.1315c-.012.9665-.805 1.7404-1.771 1.7287-.967-.0116-1.741-.8045-1.729-1.771.002-.1611.003-.3225.003-.4842s-.001-.3231-.003-.4842c-.012-.9665.762-1.7594 1.729-1.771zm-81.609 8.0428c.951-.1759 1.864.4519 2.04 1.4023.058.316.12.6306.186.9438.2.9458-.405 1.874-1.351 2.0732-.946.1993-1.874-.4059-2.073-1.3516-.072-.3414-.14-.6842-.204-1.0285-.176-.9503.452-1.8633 1.402-2.0392zm81.265 0c.951.1759 1.579 1.0889 1.403 2.0392-.064.3443-.132.6871-.204 1.0285-.199.9457-1.127 1.5509-2.073 1.3516-.946-.1992-1.551-1.1274-1.351-2.0732.066-.3132.128-.6278.186-.9438.176-.9504 1.089-1.5782 2.039-1.4023zm-79.361 7.8165c.897-.3592 1.916.0771 2.275.9743.119.2982.242.5946.369.8891.381.8882-.03 1.9172-.918 2.2984s-1.917-.0297-2.298-.9179c-.138-.3209-.272-.6439-.402-.9689-.359-.8973.077-1.9158.974-2.
275zm77.458 0c.897.3592 1.333 1.3777.974 2.275-.13.325-.264.648-.402.9689-.381.8882-1.41 1.2991-2.298.9179s-1.299-1.4102-.918-2.2984c.127-.2945.25-.5909.369-.8891.359-.8972 1.378-1.3335 2.275-.9743zm-74.056 7.2905c.81-.5278 1.894-.2993 2.422.5104.175.2691.354.5359.536.8004.547.7965.345 1.886-.451 2.4335-.797.5471-1.886.3456-2.434-.4509-.198-.288-.392-.5786-.583-.8717-.528-.8097-.3-1.8939.51-2.4217zm70.654 0c.81.5278 1.038 1.6121.51 2.4217-.191.2931-.385.5837-.583.8717-.548.7965-1.637.998-2.434.4509-.796-.5475-.998-1.637-.451-2.4335.182-.2645.361-.5313.536-.8004.528-.8097 1.612-1.0382 2.422-.5104zm-65.894 6.4864c.691-.675 1.799-.662 2.474.03.225.23.452.457.682.682.692.675.705 1.783.03 2.474-.675.692-1.783.705-2.475.03-.25-.244-.497-.491-.741-.741-.675-.692-.662-1.8.03-2.475zm61.134 0c.692.675.705 1.783.03 2.475-.244.25-.491.497-.741.741-.692.675-1.8.662-2.475-.03-.675-.691-.662-1.799.03-2.474.23-.225.457-.452.682-.682.675-.692 1.783-.705 2.474-.03zm-55.206 5.439c.548-.796 1.637-.998
2.434-.451.264.182.531.361.8.536.81.528 1.038 1.612.51 2.422-.527.81-1.612 1.038-2.421.51-.293-.191-.584-.385-.872-.583-.797-.548-.998-1.637-.451-2.434zm49.278 0c.547.797.346 1.886-.451 2.434-.288.198-.579.392-.872.583-.809.528-1.894.3-2.421-.51-.528-.81-.3-1.894.51-2.422.269-.175.536-.354.8-.536.797-.547 1.886-.345 2.434.451zm-42.405 4.183c.381-.888 1.41-1.299 2.298-.918.295.127.591.25.89.369.897.359 1.333 1.378.974 2.275s-1.378 1.333-2.275.974c-.325-.13-.648-.264-.969-.402-.888-.381-1.299-1.41-.918-2.298zm35.532 0c.381.888-.03 1.917-.918 2.298-.321.138-.644.272-.969.402-.897.359-1.916-.077-2.275-.974s.077-1.916.974-2.275c.299-.119.595-.242.89-.369.888-.381 1.917.03 2.298.918zm-27.973 2.755c.199-.946 1.128-1.551 2.073-1.351.313.066.628.128.944.186.95.176 1.578 1.089 1.402 2.039-.175.951-1.088 1.579-2.039 1.403-.344-.064-.687-.132-1.028-.204-.946-.199-1.551-1.127-1.352-2.073zm20.414 0c.199.946-.406 1.874-1.352 2.073-.341.072-.684.14-1.028.204-.951.176-1.864-.452-2.039-1.402-.176-.95
1.452-1.864 1.402-2.04.316-.058.63-.12.944-.186.945-.2 1.874.405 2.073 1.351zm-12.462 1.218c.011-.967.804-1.741 1.771-1.729.161.002.322.003.484.003s.323-.001.484-.003c.967-.012 1.76.762 1.771 1.729.012.966-.762 1.759-1.728 1.771-.044 0-.088.001-.132.001-.132.001-.263.002-.395.002-.105 0-.21 0-.315-.001-.07-.001-.141-.001-.212-.002-.966-.012-1.74-.805-1.728-1.771zm2.255-66.726c-.169 0-.338.0016-.507.0049-.966.0187-1.734.8172-1.716 1.7835.019.9663.818 1.7345 1.784 1.7158.146-.0028.292-.0042.439-.0042s.293.0014.439.0042c.966.0187 1.765-.7495 1.784-1.7158.018-.9663-.75-1.7648-1.716-1.7835-.169-.0033-.338-.0049-.507-.0049zm7.477 1.1027c-.925-.2802-1.902.2424-2.183 1.1674-.28.925.243 1.902 1.168 2.1822.279.0847.556.1746.831.2698.913.3167 1.91-.1669 2.226-1.0801.317-.9131-.167-1.9101-1.08-2.2267-.318-.1103-.639-.2146-.962-.3126zm-13.939 3.3496c.925-.2802 1.448-1.2572 1.168-2.1822-.281-.925-1.258-1.4476-2.183-1.1674-.323.098-.644.2023-.962.3126-.913.3166-1.397 1.3136-1.08 2.2267.316.9132 1.
313 1.3968 2.226 1.0801.275-.0952.552-.1851.831-.2698zm21.188.1714c-.793-.5533-1.884-.3595-2.437.4329-.553.7925-.359 1.8834.433 2.4367.239.1669.475.3384.707.5143.77.5839 1.868.4329 2.451-.3373.584-.7702.433-1.8679-.337-2.4518-.268-.2034-.541-.4018-.817-.5948zm-27.448 2.8696c.792-.5533.986-1.6442.433-2.4367-.553-.7924-1.644-.9862-2.437-.4329-.276.193-.549.3914-.817.5948-.77.5839-.921 1.6816-.337 2.4518.583.7702 1.681.9212 2.451.3373.232-.1759.468-.3474.707-.5143zm33.253 2.7135c-.583-.7701-1.681-.9211-2.451-.3372s-.922 1.6816-.338 2.4518c.176.232.348.4676.515.7066.553.7924 1.644.9862 2.436.4329.793-.5533.987-1.6442.433-2.4367-.193-.2765-.391-.549-.595-.8174zm-38.273 2.1146c.583-.7702.432-1.8679-.338-2.4518s-1.868-.4329-2.451.3373c-.204.2683-.402.5408-.595.8173-.554.7925-.36 1.8834.433 2.4367.792.5533 1.883.3595 2.436-.4329.167-.239.339-.4746.515-.7066zm42.077 4.9894c-.317-.9132-1.314-1.3968-2.227-1.0801-.913.3166-1.397 1.3136-1.08 2.2267.095.2746.185.5515.27.8308.28.925 1.257 1.4477 2
.182 1.1674.925-.2802 1.448-1.2572 1.167-2.1822-.098-.3236-.202-.6445-.312-.9626zm-45.363 1.1466c.317-.9131-.167-1.9101-1.08-2.2267-.913-.3167-1.91.1669-2.227 1.0801-.11.3181-.214.639-.312.9626-.281.925.242 1.902 1.167 2.1822.925.2803 1.902-.2424 2.182-1.1674.085-.2793.175-.5562.27-.8308zm46.773 6.7859c-.019-.9664-.817-1.7346-1.783-1.7159-.967.0187-1.735.8172-1.716 1.7835.003.146.004.2924.004.4391s-.001.2931-.004.4391c-.019.9663.749 1.7648 1.716 1.7835.966.0187 1.764-.7495 1.783-1.7159.003-.1685.005-.3374.005-.5067s-.002-.3382-.005-.5067zm-47.991.0676c.019-.9663-.749-1.7648-1.716-1.7835-.966-.0187-1.764.7495-1.783 1.7159-.003.1685-.005.3374-.005.5067s.002.3382.005.5067c.019.9664.817 1.7346 1.783 1.7159.967-.0187 1.735-.8172 1.716-1.7835-.003-.146-.004-.2924-.004-.4391s.001-.2931.004-.4391zm46.893 7.9157c.281-.925-.242-1.902-1.167-2.1822-.925-.2803-1.902.2424-2.182 1.1674-.085.2793-.175.5562-.27.8308-.317.9131.167 1.9101 1.08 2.2267.913.3167 1.91-.1669 2.227-1.0801.11-.3181.214-.639.
312-.9626zm-45.945-1.0148c-.28-.925-1.257-1.4477-2.182-1.1674-.925.2802-1.448 1.2572-1.167 2.1822.098.3236.202.6445.312.9626.317.9132 1.314 1.3968 2.227 1.0801.913-.3166 1.397-1.3136 1.08-2.2267-.095-.2746-.185-.5515-.27-.8308zm42.424 8.264c.554-.7925.36-1.8834-.433-2.4367-.792-.5534-1.883-.3595-2.436.4329-.167.239-.339.4746-.515.7066-.583.7702-.432 1.8679.338 2.4518s1.868.4329 2.451-.3372c.204-.2684.402-.5409.595-.8174zm-39.383-2.0038c-.553-.7924-1.644-.9862-2.436-.4329-.793.5533-.987 1.6442-.433 2.4367.193.2765.391.549.595.8174.583.7701 1.681.9211 2.451.3372s.922-1.6816.338-2.4518c-.176-.232-.348-.4676-.515-.7066zm33.8 7.8095c.77-.5839.921-1.6816.337-2.4518-.583-.7702-1.681-.9212-2.451-.3373-.232.1759-.468.3474-.707.5143-.792.5533-.986 1.6442-.433 2.4367.553.7924 1.644.9862 2.437.4329.276-.193.549-.3914.817-.5948zm-28.972-2.7891c-.77-.5839-1.868-.4329-2.451.3373-.584.7702-.433 1.8679.337 2.4518.268.2034.541.4018.817.5948.793.5533 1.884.3595 2.437-.4329.553-.7925.359-1.8834-.433-2.
4367-.239-.1669-.475-.3384-.707-.5143zm6.136 3.2855c-.913-.3167-1.91.1669-2.226 1.0801-.317.9131.167 1.9101 1.08 2.2267.318.1103.639.2146.962.3126.925.2802 1.902-.2424 2.183-1.1674.28-.925-.243-1.902-1.168-2.1822-.279-.0847-.556-.1746-.831-.2698zm15.732 3.3068c.913-.3166 1.397-1.3136 1.08-2.2267-.316-.9132-1.313-1.3968-2.226-1.0801-.275.0952-.552.1851-.831.2698-.925.2802-1.448 1.2572-1.168 2.1822.281.925 1.258 1.4476 2.183 1.1674.323-.098.644-.2023.962-.3126zm-8.878-2.0889c-.966-.0187-1.765.7495-1.784 1.7158-.018.9663.75 1.7644 1.716 1.7834.169.003.338.005.507.005s.338-.002.507-.005c.966-.019 1.734-.8171 1.716-1.7834-.019-.9663-.818-1.7345-1.784-1.7158-.146.0028-.292.0042-.439.0042s-.293-.0014-.439-.0042z"/>
+ <path d="m3.75 75c0-39.3503 31.8997-71.25 71.25-71.25 39.35 0 71.25 31.8997 71.25 71.25 0 39.35-31.9 71.25-71.25 71.25-39.3503 0-71.25-31.9-71.25-71.25zm71.25-74.75c-41.2833 0-74.75 33.4667-74.75 74.75 0 41.283 33.4667 74.75 74.75 74.75 41.283 0 74.75-33.467 74.75-74.75 0-41.2833-33.467-74.75-74.75-74.75zm-55.25 74.75c0-30.5137 24.7363-55.25 55.25-55.25 30.514 0 55.25 24.7363 55.25 55.25 0 30.514-24.736 55.25-55.25 55.25-30.5137 0-55.25-24.736-55.25-55.25zm55.25-58.75c-32.4467 0-58.75 26.3033-58.75 58.75 0 32.447 26.3033 58.75 58.75 58.75 32.447 0 58.75-26.303 58.75-58.75 0-32.4467-26.303-58.75-58.75-58.75zm0 19.5c-21.6772 0-39.25 17.5728-39.25 39.25s17.5728 39.25 39.25 39.25 39.25-17.5728 39.25-39.25-17.5728-39.25-39.25-39.25zm-42.75 39.25c0-23.6102 19.1398-42.75 42.75-42.75s42.75 19.1398 42.75 42.75-19.1398 42.75-42.75 42.75-42.75-19.1398-42.75-42.75zm20.5 0c0-12.2883 9.9617-22.25 22.25-22.25s22.25 9.9617 22.25 22.25-9.9617 22.25-22.25 22.25-22.25-9.9617-22.25-22.25zm2
2.25-25.75c-14.2213 0-25.75 11.5287-25.75 25.75s11.5287 25.75 25.75 25.75 25.75-11.5287 25.75-25.75-11.5287-25.75-25.75-25.75z"/>
+ <path d="m228.75 225c0-39.35 31.9-71.25 71.25-71.25s71.25 31.9 71.25 71.25-31.9 71.25-71.25 71.25-71.25-31.9-71.25-71.25zm71.25-74.75c-41.283 0-74.75 33.467-74.75 74.75s33.467 74.75 74.75 74.75 74.75-33.467 74.75-74.75-33.467-74.75-74.75-74.75zm-55.25 74.75c0-30.514 24.736-55.25 55.25-55.25s55.25 24.736 55.25 55.25-24.736 55.25-55.25 55.25-55.25-24.736-55.25-55.25zm55.25-58.75c-32.447 0-58.75 26.303-58.75 58.75s26.303 58.75 58.75 58.75 58.75-26.303 58.75-58.75-26.303-58.75-58.75-58.75zm0 19.5c-21.677 0-39.25 17.573-39.25 39.25s17.573 39.25 39.25 39.25 39.25-17.573 39.25-39.25-17.573-39.25-39.25-39.25zm-42.75 39.25c0-23.61 19.14-42.75 42.75-42.75s42.75 19.14 42.75 42.75-19.14 42.75-42.75 42.75-42.75-19.14-42.75-42.75zm20.5 0c0-12.288 9.962-22.25 22.25-22.25s22.25 9.962 22.25 22.25-9.962 22.25-22.25 22.25-22.25-9.962-22.25-22.25zm22.25-25.75c-14.221 0-25.75 11.529-25.75 25.75s11.529 25.75 25.75 25.75 25.75-11.529 25.75-25.75-11.529-25.75-25.75-25.75z"/>
+ <path d="m828.75 225c0-39.35 31.9-71.25 71.25-71.25v-3.5c-41.283 0-74.75 33.467-74.75 74.75s33.467 74.75 74.75 74.75v-3.5c-39.35 0-71.25-31.9-71.25-71.25zm16 0c0-30.514 24.736-55.25 55.25-55.25v-3.5c-32.447 0-58.75 26.303-58.75 58.75s26.303 58.75 58.75 58.75v-3.5c-30.514 0-55.25-24.736-55.25-55.25zm55.25-39.25c-21.677 0-39.25 17.573-39.25 39.25s17.573 39.25 39.25 39.25v3.5c-23.61 0-42.75-19.14-42.75-42.75s19.14-42.75 42.75-42.75zm-22.25 39.25c0-12.288 9.962-22.25 22.25-22.25v-3.5c-14.221 0-25.75 11.529-25.75 25.75s11.529 25.75 25.75 25.75v-3.5c-12.288 0-22.25-9.962-22.25-22.25z"/>
+ <path d="m71.25 225c0-39.35-31.8997-71.25-71.25-71.25v-3.5c41.2833 0 74.75 33.467 74.75 74.75s-33.4667 74.75-74.75 74.75v-3.5c39.3503 0 71.25-31.9 71.25-71.25zm-16 0c0-30.514-24.7363-55.25-55.25-55.25v-3.5c32.4467 0 58.75 26.303 58.75 58.75s-26.3033 58.75-58.75 58.75v-3.5c30.5137 0 55.25-24.736 55.25-55.25zm-55.25-39.25c21.6772 0 39.25 17.573 39.25 39.25s-17.5728 39.25-39.25 39.25v3.5c23.6102 0 42.75-19.14 42.75-42.75s-19.1398-42.75-42.75-42.75zm22.25 39.25c0-12.288-9.9617-22.25-22.25-22.25v-3.5c14.2213 0 25.75 11.529 25.75 25.75s-11.5287 25.75-25.75 25.75v-3.5c12.2883 0 22.25-9.962 22.25-22.25z"/>
+ <path d="m303.75 75c0-39.3503 31.9-71.25 71.25-71.25s71.25 31.8997 71.25 71.25c0 39.35-31.9 71.25-71.25 71.25s-71.25-31.9-71.25-71.25zm71.25-74.75c-41.283 0-74.75 33.4667-74.75 74.75 0 41.283 33.467 74.75 74.75 74.75s74.75-33.467 74.75-74.75c0-41.2833-33.467-74.75-74.75-74.75zm-55.25 74.75c0-30.5137 24.736-55.25 55.25-55.25s55.25 24.7363 55.25 55.25c0 30.514-24.736 55.25-55.25 55.25s-55.25-24.736-55.25-55.25zm55.25-58.75c-32.447 0-58.75 26.3033-58.75 58.75 0 32.447 26.303 58.75 58.75 58.75s58.75-26.303 58.75-58.75c0-32.4467-26.303-58.75-58.75-58.75zm0 19.5c-21.677 0-39.25 17.5728-39.25 39.25s17.573 39.25 39.25 39.25 39.25-17.5728 39.25-39.25-17.573-39.25-39.25-39.25zm-42.75 39.25c0-23.6102 19.14-42.75 42.75-42.75s42.75 19.1398 42.75 42.75-19.14 42.75-42.75 42.75-42.75-19.1398-42.75-42.75zm20.5 0c0-12.2883 9.962-22.25 22.25-22.25s22.25 9.9617 22.25 22.25-9.962 22.25-22.25 22.25-22.25-9.9617-22.25-22.25zm22.25-25.75c-14.221 0-25.75 11.5287-25.75 25.75s11.529 25.75 25.75 25
.75 25.75-11.5287 25.75-25.75-11.529-25.75-25.75-25.75z"/>
+ <path d="m603.75 75c0-39.3503 31.9-71.25 71.25-71.25s71.25 31.8997 71.25 71.25c0 39.35-31.9 71.25-71.25 71.25s-71.25-31.9-71.25-71.25zm71.25-74.75c-41.283 0-74.75 33.4667-74.75 74.75 0 41.283 33.467 74.75 74.75 74.75s74.75-33.467 74.75-74.75c0-41.2833-33.467-74.75-74.75-74.75zm-55.25 74.75c0-30.5137 24.736-55.25 55.25-55.25s55.25 24.7363 55.25 55.25c0 30.514-24.736 55.25-55.25 55.25s-55.25-24.736-55.25-55.25zm55.25-58.75c-32.447 0-58.75 26.3033-58.75 58.75 0 32.447 26.303 58.75 58.75 58.75s58.75-26.303 58.75-58.75c0-32.4467-26.303-58.75-58.75-58.75zm0 19.5c-21.677 0-39.25 17.5728-39.25 39.25s17.573 39.25 39.25 39.25 39.25-17.5728 39.25-39.25-17.573-39.25-39.25-39.25zm-42.75 39.25c0-23.6102 19.14-42.75 42.75-42.75s42.75 19.1398 42.75 42.75-19.14 42.75-42.75 42.75-42.75-19.1398-42.75-42.75zm20.5 0c0-12.2883 9.962-22.25 22.25-22.25s22.25 9.9617 22.25 22.25-9.962 22.25-22.25 22.25-22.25-9.9617-22.25-22.25zm22.25-25.75c-14.221 0-25.75 11.5287-25.75 25.75s11.529 25.75 25.75 25
.75 25.75-11.5287 25.75-25.75-11.529-25.75-25.75-25.75z"/>
+ <path d="m150 150.25c-.878 0-1.753.015-2.624.045-.966.034-1.722.844-1.689 1.81.033.965.843 1.721 1.809 1.688.831-.029 1.666-.043 2.504-.043s1.673.014 2.504.043c.966.033 1.776-.723 1.809-1.688.033-.966-.723-1.776-1.689-1.81-.871-.03-1.746-.045-2.624-.045zm-11.449 4.415c.954-.154 1.603-1.053 1.449-2.007s-1.053-1.603-2.007-1.449c-1.735.281-3.45.621-5.143 1.018-.941.221-1.525 1.163-1.304 2.104s1.163 1.524 2.104 1.303c1.613-.378 3.248-.702 4.901-.969zm23.456-3.456c-.954-.154-1.853.495-2.007 1.449s.495 1.853 1.449 2.007c1.653.267 3.288.591 4.901.969.941.221 1.883-.362 2.104-1.303s-.363-1.883-1.304-2.104c-1.693-.397-3.408-.737-5.143-1.018zm-36.956 7.031c.905-.339 1.365-1.347 1.026-2.252-.338-.906-1.347-1.365-2.252-1.027-1.642.615-3.258 1.285-4.843 2.009-.879.401-1.266 1.439-.865 2.319.402.879 1.44 1.266 2.319.865 1.511-.69 3.05-1.329 4.615-1.914zm51.124-3.279c-.905-.338-1.914.121-2.252 1.027-.339.905.121 1.913 1.026 2.252 1.565.585 3.104 1.224 4.615 1.914.879.401 1.917.014 2.31
9-.865.401-.88.014-1.918-.865-2.319-1.585-.724-3.201-1.394-4.843-2.009zm-63.661 9.436c.821-.51 1.074-1.588.565-2.41-.509-.821-1.588-1.074-2.41-.565-1.487.922-2.94 1.895-4.355 2.916-.784.565-.961 1.659-.395 2.443.565.784 1.659.961 2.443.395 1.349-.973 2.734-1.9 4.152-2.779zm76.817-2.975c-.822-.509-1.901-.256-2.41.565-.509.822-.256 1.9.565 2.41 1.418.879 2.803 1.806 4.152 2.779.784.566 1.878.389 2.443-.395.566-.784.389-1.878-.395-2.443-1.415-1.021-2.868-1.994-4.355-2.916zm-87.915 11.461c.707-.659.745-1.767.086-2.474-.659-.706-1.7663-.745-2.4731-.086-1.2779 1.192-2.5139 2.428-3.7057 3.706-.6591.707-.6205 1.814.0863 2.473s1.8142.621 2.4733-.086c1.1363-1.218 2.3152-2.397 3.5332-3.533zm99.555-2.56c-.707-.659-1.814-.62-2.473.086-.659.707-.621 1.815.086 2.474 1.218 1.136 2.397 2.315 3.533 3.533.659.707 1.767.745 2.474.086.706-.659.745-1.766.086-2.473-1.192-1.278-2.428-2.514-3.706-3.706zm-108.7948 13.039c.5655-.784.3884-1.878-.3954-2.443-.7838-.566-1.8776-.389-2.4431.395-1.021 1.415-1.9938 2
.868-2.9158 4.355-.5092.822-.2561 1.901.5653 2.41.8215.509 1.9003.256 2.4095-.565.8789-1.418 1.8061-2.803 2.7795-4.152zm118.4858-2.048c-.565-.784-1.659-.961-2.443-.395-.784.565-.961 1.659-.395 2.443.973 1.349 1.9 2.734 2.779 4.152.51.821 1.588 1.074 2.41.565.821-.509 1.074-1.588.565-2.41-.922-1.487-1.895-2.94-2.916-4.355zm-125.5085 14.122c.4015-.879.0143-1.917-.8649-2.319-.8792-.401-1.9173-.014-2.3188.865-.724 1.585-1.3942 3.201-2.0083 4.843-.3385.905.121 1.914 1.0263 2.252.9053.339 1.9135-.121 2.252-1.026.5852-1.565 1.2238-3.104 1.9137-4.615zm132.8765-1.454c-.401-.879-1.439-1.266-2.319-.865-.879.402-1.266 1.44-.865 2.319.69 1.511 1.329 3.05 1.914 4.615.339.905 1.347 1.365 2.252 1.026.906-.338 1.365-1.347 1.027-2.252-.615-1.642-1.285-3.258-2.009-4.843zm-137.3955 14.668c.2209-.941-.3628-1.883-1.3037-2.104s-1.8828.363-2.1037 1.304c-.3975 1.693-.7374 3.408-1.0176 5.143-.1541.954.4944 1.853 1.4486 2.007.9541.154 1.8525-.495 2.0066-1.449.267-1.653.591-3.288.9698-4.901zm142.1385-.8c-.221-
.941-1.163-1.525-2.104-1.304s-1.524 1.163-1.303 2.104c.378 1.613.702 3.248.969 4.901.154.954 1.053 1.603 2.007 1.449s1.603-1.053 1.449-2.007c-.281-1.735-.621-3.45-1.018-5.143zm-143.9799 14.646c.0334-.966-.7226-1.776-1.6885-1.809-.966-.033-1.776.723-1.8094 1.689-.03.871-.0452 1.746-.0452 2.624s.0152 1.753.0452 2.624c.0334.966.8434 1.722 1.8094 1.689.9659-.033 1.7219-.843 1.6885-1.809-.0286-.831-.0431-1.666-.0431-2.504s.0145-1.673.0431-2.504zm145.9119-.12c-.034-.966-.844-1.722-1.81-1.689-.965.033-1.721.843-1.688 1.809.029.831.043 1.666.043 2.504s-.014 1.673-.043 2.504c-.033.966.723 1.776 1.688 1.809.966.033 1.776-.723 1.81-1.689.03-.871.045-1.746.045-2.624s-.015-1.753-.045-2.624zm-145.0403 14.073c-.1541-.954-1.0525-1.603-2.0066-1.449-.9542.154-1.6027 1.053-1.4486 2.007.2802 1.735.6201 3.45 1.0176 5.143.2209.941 1.1628 1.525 2.1037 1.304s1.5246-1.163 1.3037-2.104c-.3788-1.613-.7028-3.248-.9698-4.901zm144.1263.558c.154-.954-.495-1.853-1.449-2.007s-1.853.495-2.007 1.449c-.267 1.653-.591
3.288-.969 4.901-.221.941.362 1.883 1.303 2.104s1.883-.363 2.104-1.304c.397-1.693.737-3.408 1.018-5.143zm-140.5512 12.942c-.3385-.905-1.3467-1.365-2.252-1.026-.9053.338-1.3648 1.347-1.0263 2.252.6141 1.642 1.2843 3.258 2.0083 4.843.4015.879 1.4396 1.266 2.3188.865.8792-.402 1.2664-1.44.8649-2.319-.6899-1.511-1.3285-3.05-1.9137-4.615zm136.7992 1.226c.338-.905-.121-1.914-1.027-2.252-.905-.339-1.913.121-2.252 1.026-.585 1.565-1.224 3.104-1.914 4.615-.401.879-.014 1.917.865 2.319.88.401 1.918.014 2.319-.865.724-1.585 1.394-3.201 2.009-4.843zm-130.6423 11.311c-.5093-.821-1.588-1.074-2.4095-.565-.8214.509-1.0745 1.588-.5653 2.41.922 1.487 1.8948 2.94 2.9158 4.355.5655.784 1.6593.961 2.4431.395.7838-.565.9609-1.659.3954-2.443-.9734-1.349-1.9006-2.734-2.7795-4.152zm124.1813 1.845c.509-.822.256-1.901-.565-2.41-.822-.509-1.9-.256-2.41.565-.879 1.418-1.806 2.803-2.779 4.152-.566.784-.389 1.878.395 2.443.784.566 1.878.389 2.443-.395 1.021-1.415 1.994-2.868 2.916-4.355zm-115.6952 9.253c-.6592-.7
07-1.7665-.745-2.4733-.086s-.7455 1.766-.0863 2.473c1.1918 1.278 2.4278 2.514 3.7057 3.706.7068.659 1.8141.62 2.4731-.086.659-.707.621-1.815-.086-2.474-1.218-1.136-2.3969-2.315-3.5332-3.533zm106.7942 2.387c.659-.707.62-1.814-.086-2.473-.707-.659-1.815-.621-2.474.086-1.136 1.218-2.315 2.397-3.533 3.533-.707.659-.745 1.767-.086 2.474.659.706 1.766.745 2.473.086 1.278-1.192 2.514-2.428 3.706-3.706zm-96.315 6.853c-.784-.566-1.878-.389-2.443.395-.566.784-.389 1.878.395 2.443 1.415 1.021 2.868 1.994 4.355 2.916.822.509 1.901.256 2.41-.565.509-.822.256-1.9-.565-2.41-1.418-.879-2.803-1.806-4.152-2.779zm85.324 2.838c.784-.565.961-1.659.395-2.443-.565-.784-1.659-.961-2.443-.395-1.349.973-2.734 1.9-4.152 2.779-.821.51-1.074 1.588-.565 2.41.509.821 1.588 1.074 2.41.565 1.487-.922 2.94-1.895 4.355-2.916zm-73.25 4.184c-.879-.401-1.917-.014-2.319.865-.401.88-.014 1.918.865 2.319 1.585.724 3.201 1.394 4.843 2.009.905.338 1.914-.121 2.252-1.027.339-.905-.121-1.913-1.026-2.252-1.565-.585-3.104-1.224-
4.615-1.914zm60.582 3.184c.879-.401 1.266-1.439.865-2.319-.402-.879-1.44-1.266-2.319-.865-1.511.69-3.05 1.329-4.615 1.914-.905.339-1.365 1.347-1.026 2.252.338.906 1.347 1.365 2.252 1.027 1.642-.615 3.258-1.285 4.843-2.009zm-47.368 1.336c-.941-.221-1.883.362-2.104 1.303s.363 1.883 1.304 2.104c1.693.397 3.408.737 5.143 1.018.954.154 1.853-.495 2.007-1.449s-.495-1.853-1.449-2.007c-1.653-.267-3.288-.591-4.901-.969zm33.5 3.407c.941-.221 1.525-1.163 1.304-2.104s-1.163-1.524-2.104-1.303c-1.613.378-3.248.702-4.901.969-.954.154-1.603 1.053-1.449 2.007s1.053 1.603 2.007 1.449c1.735-.281 3.45-.621 5.143-1.018zm-19.654-1.566c-.966-.033-1.776.723-1.809 1.688-.033.966.723 1.776 1.689 1.81.871.03 1.746.045 2.624.045s1.753-.015 2.624-.045c.966-.034 1.722-.844 1.689-1.81-.033-.965-.843-1.721-1.809-1.688-.831.029-1.666.043-2.504.043s-1.673-.014-2.504-.043zm2.504-130.957c-.802 0-1.601.016-2.396.047-.965.038-1.717.852-1.679 1.818s.852 1.718 1.817 1.679c.749-.029 1.502-.044 2.258-.044s1.509.015 2.258.04
4c.966.039 1.779-.713 1.817-1.679s-.714-1.78-1.679-1.818c-.795-.031-1.594-.047-2.396-.047zm-10.317 4.444c.95-.176 1.578-1.09 1.402-2.04s-1.089-1.578-2.04-1.402c-1.579.293-3.136.648-4.668 1.062-.933.252-1.485 1.213-1.233 2.146s1.213 1.485 2.146 1.233c1.442-.39 2.907-.724 4.393-.999zm21.272-3.442c-.951-.176-1.864.452-2.04 1.402s.452 1.864 1.402 2.04c1.486.275 2.951.609 4.393.999.933.252 1.894-.3 2.146-1.233s-.3-1.894-1.233-2.146c-1.532-.414-3.089-.769-4.668-1.062zm12.799 3.907c-.887-.385-1.917.022-2.302.909-.384.887.023 1.917.909 2.302 1.383.599 2.737 1.253 4.059 1.958.853.454 1.913.132 2.368-.721.454-.853.132-1.913-.721-2.368-1.405-.749-2.844-1.443-4.313-2.08zm-46.115 3.211c.886-.385 1.293-1.415.909-2.302-.385-.887-1.415-1.294-2.302-.909-1.469.637-2.908 1.331-4.313 2.08-.853.455-1.175 1.515-.721 2.368.455.853 1.515 1.175 2.368.721 1.322-.705 2.676-1.359 4.059-1.958zm-10.921 6.278c.779-.573.946-1.668.373-2.447-.572-.778-1.667-.945-2.446-.373-1.287.946-2.535 1.943-3.741 2.987-.731.633-
.81 1.738-.177 2.469.632.73 1.738.81 2.468.177 1.136-.983 2.311-1.922 3.523-2.813zm68.637-2.82c-.779-.572-1.874-.405-2.446.373-.573.779-.406 1.874.373 2.447 1.212.891 2.387 1.83 3.523 2.813.73.633 1.836.553 2.468-.177.633-.731.554-1.836-.177-2.469-1.206-1.044-2.454-2.041-3.741-2.987zm-77.894 11.367c.633-.73.553-1.836-.177-2.468-.731-.633-1.836-.554-2.469.177-1.044 1.206-2.041 2.454-2.987 3.741-.572.779-.405 1.874.373 2.446.779.573 1.874.406 2.447-.373.891-1.212 1.83-2.387 2.813-3.523zm87.724-2.291c-.633-.731-1.738-.81-2.469-.177-.73.632-.81 1.738-.177 2.468.983 1.136 1.922 2.311 2.813 3.523.573.779 1.668.946 2.447.373.778-.572.945-1.667.373-2.446-.946-1.287-1.943-2.535-2.987-3.741zm7.576 11.029c-.455-.853-1.515-1.175-2.368-.721-.853.455-1.175 1.515-.721 2.368.705 1.322 1.359 2.676 1.958 4.059.385.886 1.415 1.293 2.302.909.887-.385 1.294-1.415.909-2.302-.637-1.469-1.331-2.908-2.08-4.313zm-102.433 1.647c.454-.853.132-1.913-.7213-2.368-.8529-.454-1.9128-.132-2.3675.721-.7489 1.405-1.44
33 2.844-2.0805 4.313-.3846.887.0224 1.917.9091 2.302.8867.384 1.9173-.023 2.3019-.909.5996-1.383 1.2532-2.737 1.9583-4.059zm-4.6354 11.71c.2521-.933-.2999-1.894-1.233-2.146-.933-.252-1.8937.3-2.1459 1.233-.4141 1.532-.7688 3.089-1.0614 4.668-.1761.951.4515 1.864 1.4018 2.04s1.8635-.452 2.0396-1.402c.2754-1.486.6092-2.951.9989-4.393zm111.9934-.913c-.252-.933-1.213-1.485-2.146-1.233s-1.485 1.213-1.233 2.146c.39 1.442.724 2.907.999 4.393.176.95 1.09 1.578 2.04 1.402s1.578-1.089 1.402-2.04c-.293-1.579-.648-3.136-1.062-4.668zm-113.8915 13.365c.0381-.966-.7139-1.779-1.6797-1.817-.9657-.038-1.7795.714-1.8176 1.679-.0314.795-.0472 1.594-.0472 2.396s.0158 1.601.0472 2.396c.0381.965.8519 1.717 1.8176 1.679.9658-.038 1.7178-.852 1.6797-1.817-.0296-.749-.0445-1.502-.0445-2.258s.0149-1.509.0445-2.258zm115.9085-.138c-.038-.965-.852-1.717-1.818-1.679s-1.718.852-1.679 1.817c.029.749.044 1.502.044 2.258s-.015 1.509-.044 2.258c-.039.966.713 1.779 1.679 1.817s1.78-.714 1.818-1.679c.031-.795.047-1.594
.047-2.396s-.016-1.601-.047-2.396zm-115.0093 12.713c-.1761-.95-1.0893-1.578-2.0396-1.402s-1.5779 1.089-1.4018 2.04c.2926 1.579.6473 3.136 1.0614 4.668.2521.933 1.2129 1.485 2.1459 1.233.9331-.252 1.4851-1.213 1.233-2.146-.3897-1.442-.7235-2.907-.9989-4.393zm114.0543.638c.176-.951-.452-1.864-1.402-2.04s-1.864.452-2.04 1.402c-.275 1.486-.609 2.951-.999 4.393-.252.933.3 1.894 1.233 2.146s1.894-.3 2.146-1.233c.414-1.532.769-3.089 1.062-4.668zm-110.3783 11.406c-.3846-.886-1.4152-1.293-2.3019-.909-.8867.385-1.2937 1.415-.9091 2.302.6372 1.469 1.3316 2.908 2.0805 4.313.4547.853 1.5146 1.175 2.3675.721.8533-.455 1.1753-1.515.7213-2.368-.7051-1.322-1.3587-2.676-1.9583-4.059zm106.4713 1.393c.385-.887-.022-1.917-.909-2.302-.887-.384-1.917.023-2.302.909-.599 1.383-1.253 2.737-1.958 4.059-.454.853-.132 1.913.721 2.368.853.454 1.913.132 2.368-.721.749-1.405 1.443-2.844 2.08-4.313zm-100.193 9.528c-.573-.779-1.668-.946-2.447-.373-.778.572-.945 1.667-.373 2.446.946 1.287 1.943 2.535 2.987 3.741.633.
731 1.738.81 2.469.177.73-.632.81-1.738.177-2.468-.983-1.136-1.922-2.311-2.813-3.523zm93.524 2.073c.572-.779.405-1.874-.373-2.446-.779-.573-1.874-.406-2.447.373-.891 1.212-1.83 2.387-2.813 3.523-.633.73-.553 1.836.177 2.468.731.633 1.836.554 2.469-.177 1.044-1.206 2.041-2.454 2.987-3.741zm-84.977 7.184c-.73-.633-1.836-.553-2.468.177-.633.731-.554 1.836.177 2.469 1.206 1.044 2.454 2.041 3.741 2.987.779.572 1.874.405 2.446-.373.573-.779.406-1.874-.373-2.447-1.212-.891-2.387-1.83-3.523-2.813zm75.901 2.646c.731-.633.81-1.738.177-2.469-.632-.73-1.738-.81-2.468-.177-1.136.983-2.311 1.922-3.523 2.813-.779.573-.946 1.668-.373 2.447.572.778 1.667.945 2.446.373 1.287-.946 2.535-1.943 3.741-2.987zm-65.516 4.487c-.853-.454-1.913-.132-2.368.721-.454.853-.132 1.913.721 2.368 1.405.749 2.844 1.443 4.313 2.08.887.385 1.917-.022 2.302-.909.384-.887-.023-1.917-.909-2.302-1.383-.599-2.737-1.253-4.059-1.958zm54.487 3.089c.853-.455 1.175-1.515.721-2.368-.455-.853-1.515-1.175-2.368-.721-1.322.705-2.676 1
.359-4.059 1.958-.886.385-1.293 1.415-.909 2.302.385.887 1.415 1.294 2.302.909 1.469-.637 2.908-1.331 4.313-2.08zm-42.777 1.546c-.933-.252-1.894.3-2.146 1.233s.3 1.894 1.233 2.146c1.532.414 3.089.769 4.668 1.062.951.176 1.864-.452 2.04-1.402s-.452-1.864-1.402-2.04c-1.486-.275-2.951-.609-4.393-.999zm30.333 3.379c.933-.252 1.485-1.213 1.233-2.146s-1.213-1.485-2.146-1.233c-1.442.39-2.907.724-4.393.999-.95.176-1.578 1.09-1.402 2.04s1.089 1.578 2.04 1.402c1.579-.293 3.136-.648 4.668-1.062zm-17.881-1.48c-.966-.039-1.779.713-1.817 1.679s.714 1.78 1.679 1.818c.795.031 1.594.047 2.396.047s1.601-.016 2.396-.047c.965-.038 1.717-.852 1.679-1.818s-.852-1.718-1.817-1.679c-.749.029-1.502.044-2.258.044s-1.509-.015-2.258-.044zm-.139-98.89c.794-.044 1.593-.066 2.397-.066s1.603.022 2.397.066c.965.053 1.704.879 1.65 1.844-.053.965-.878 1.704-1.843 1.651-.73-.041-1.464-.061-2.204-.061s-1.474.02-2.204.061c-.965.053-1.79-.686-1.843-1.651-.054-.965.685-1.791 1.65-1.844zm-6.378 2.587c.247.934-.312 1.891-1.2
46 2.137-1.429.377-2.826.831-4.186 1.36-.901.35-1.915-.097-2.265-.998s.097-1.915.997-2.265c1.483-.576 3.005-1.071 4.563-1.481.934-.246 1.891.312 2.137 1.247zm17.55 0c.246-.935 1.203-1.493 2.137-1.247 1.558.41 3.08.905 4.563 1.481.901.35 1.347 1.364.997 2.265s-1.364 1.348-2.265.998c-1.36-.529-2.757-.983-4.186-1.36-.934-.246-1.493-1.203-1.246-2.137zm-29.509 4.675c.525.812.291 1.895-.521 2.419-1.236.798-2.424 1.663-3.559 2.591-.749.611-1.851.5-2.463-.248-.611-.749-.5-1.851.248-2.463 1.236-1.01 2.53-1.952 3.876-2.82.812-.525 1.895-.291 2.419.521zm41.468 0c.524-.812 1.607-1.046 2.419-.521 1.346.868 2.64 1.81 3.876 2.82.748.612.859 1.714.248 2.463-.612.748-1.714.859-2.463.248-1.135-.928-2.323-1.793-3.559-2.591-.812-.524-1.046-1.607-.521-2.419zm-51.394 8.145c.748.612.859 1.714.248 2.463-.928 1.135-1.793 2.323-2.591 3.559-.524.812-1.607 1.046-2.419.521-.812-.524-1.046-1.607-.521-2.419.868-1.346 1.81-2.64 2.82-3.876.612-.748 1.714-.859 2.463-.248zm61.32 0c.749-.611 1.851-.5 2.463.248 1.01 1.
236 1.952 2.53 2.82 3.876.525.812.291 1.895-.521 2.419-.812.525-1.895.291-2.419-.521-.798-1.236-1.663-2.424-2.591-3.559-.611-.749-.5-1.851.248-2.463zm-68.258 10.805c.901.35 1.348 1.364.998 2.265-.529 1.36-.983 2.757-1.36 4.186-.246.934-1.203 1.493-2.137 1.246-.935-.246-1.493-1.203-1.247-2.137.41-1.558.905-3.08 1.481-4.563.35-.9 1.364-1.347 2.265-.997zm75.196 0c.901-.35 1.915.097 2.265.997.576 1.483 1.071 3.005 1.481 4.563.246.934-.312 1.891-1.247 2.137-.934.247-1.891-.312-2.137-1.246-.377-1.429-.831-2.826-1.36-4.186-.35-.901.097-1.915.998-2.265zm-78.438 12.425c.965.053 1.704.878 1.651 1.843-.041.73-.061 1.464-.061 2.204s.02 1.474.061 2.204c.053.965-.686 1.79-1.651 1.843-.965.054-1.791-.685-1.844-1.65-.044-.794-.066-1.593-.066-2.397s.022-1.603.066-2.397c.053-.965.879-1.704 1.844-1.65zm81.68 0c.965-.054 1.791.685 1.844 1.65.044.794.066 1.593.066 2.397s-.022 1.603-.066 2.397c-.053.965-.879 1.704-1.844 1.65-.965-.053-1.704-.878-1.651-1.843.041-.73.061-1.464.061-2.204s-.02-1.474-.061-2.2
04c-.053-.965.686-1.79 1.651-1.843zm-80.937 12.822c.934-.247 1.891.312 2.137 1.246.377 1.429.831 2.826 1.36 4.186.35.901-.097 1.915-.998 2.265s-1.915-.097-2.265-.997c-.576-1.483-1.071-3.005-1.481-4.563-.246-.934.312-1.891 1.247-2.137zm80.194 0c.935.246 1.493 1.203 1.247 2.137-.41 1.558-.905 3.08-1.481 4.563-.35.901-1.364 1.347-2.265.997s-1.348-1.364-.998-2.265c.529-1.36.983-2.757 1.36-4.186.246-.934 1.203-1.493 2.137-1.246zm-75.519 11.959c.812-.525 1.895-.291 2.419.521.798 1.236 1.663 2.424 2.591 3.559.611.749.5 1.851-.248 2.463-.749.611-1.851.5-2.463-.248-1.01-1.236-1.952-2.53-2.82-3.876-.525-.812-.291-1.895.521-2.419zm70.844 0c.812.524 1.046 1.607.521 2.419-.868 1.346-1.81 2.64-2.82 3.876-.612.748-1.714.859-2.463.248-.748-.612-.859-1.714-.248-2.463.928-1.135 1.793-2.323 2.591-3.559.524-.812 1.607-1.046 2.419-.521zm-62.699 9.926c.612-.748 1.714-.859 2.463-.248 1.135.928 2.323 1.793 3.559 2.591.812.524 1.046 1.607.521 2.419-.524.812-1.607 1.046-2.419.521-1.346-.868-2.64-1.81-3.876-2
.82-.748-.612-.859-1.714-.248-2.463zm54.554 0c.611.749.5 1.851-.248 2.463-1.236 1.01-2.53 1.952-3.876 2.82-.812.525-1.895.291-2.419-.521-.525-.812-.291-1.895.521-2.419 1.236-.798 2.424-1.663 3.559-2.591.749-.611 1.851-.5 2.463.248zm-43.749 6.938c.35-.901 1.364-1.348 2.265-.998 1.36.529 2.757.983 4.186 1.36.934.246 1.493 1.203 1.246 2.137-.246.935-1.203 1.493-2.137 1.247-1.558-.41-3.08-.905-4.563-1.481-.9-.35-1.347-1.364-.997-2.265zm32.944 0c.35.901-.097 1.915-.997 2.265-1.483.576-3.005 1.071-4.563 1.481-.934.246-1.891-.312-2.137-1.247-.247-.934.312-1.891 1.246-2.137 1.429-.377 2.826-.831 4.186-1.36.901-.35 1.915.097 2.265.998zm-20.519 3.242c.053-.965.878-1.704 1.843-1.651.73.041 1.464.061 2.204.061s1.474-.02 2.204-.061c.965-.053 1.79.686 1.843 1.651.054.965-.685 1.791-1.65 1.844-.794.044-1.593.066-2.397.066s-1.603-.022-2.397-.066c-.965-.053-1.704-.879-1.65-1.844zm4.047-66.59c-.81 0-1.612.037-2.403.111-.963.089-1.671.941-1.582 1.904.09.962.942 1.67 1.904 1.581.685-.064 1.379-.096 2.0
81-.096s1.396.032 2.081.096c.962.089 1.814-.619 1.904-1.581.089-.963-.619-1.815-1.582-1.904-.791-.074-1.593-.111-2.403-.111zm10.74 2.34c-.878-.403-1.917-.018-2.32.86-.404.878-.019 1.917.859 2.321 1.267.582 2.47 1.28 3.596 2.08.788.56 1.88.375 2.44-.412.56-.788.376-1.881-.412-2.441-1.303-.925-2.695-1.733-4.163-2.408zm-20.019 3.181c.878-.404 1.263-1.443.859-2.321-.403-.878-1.442-1.263-2.32-.86-1.468.675-2.86 1.483-4.163 2.408-.788.56-.972 1.653-.412 2.441.56.787 1.652.972 2.44.412 1.126-.8 2.329-1.498 3.596-2.08zm30.281 5.326c-.56-.788-1.653-.972-2.441-.412s-.972 1.652-.412 2.44c.8 1.126 1.498 2.329 2.08 3.596.404.878 1.443 1.263 2.321.859.878-.403 1.263-1.442.86-2.32-.675-1.468-1.483-2.86-2.408-4.163zm-39.151 2.028c.56-.788.375-1.88-.412-2.44-.788-.56-1.881-.376-2.441.412-.925 1.303-1.733 2.695-2.408 4.163-.403.878-.018 1.917.86 2.32.878.404 1.917.019 2.321-.859.582-1.267 1.28-2.47 2.08-3.596zm-4.005 10.794c.089-.962-.619-1.814-1.581-1.904-.963-.089-1.815.619-1.904 1.582-.074.791-.11
1 1.593-.111 2.403s.037 1.612.111 2.403c.089.963.941 1.671 1.904 1.582.962-.09 1.67-.942 1.581-1.904-.064-.685-.096-1.379-.096-2.081s.032-1.396.096-2.081zm47.793-.322c-.089-.963-.941-1.671-1.904-1.582-.962.09-1.67.942-1.581 1.904.064.685.096 1.379.096 2.081s-.032 1.396-.096 2.081c-.089.962.619 1.814 1.581 1.904.963.089 1.815-.619 1.904-1.582.074-.791.111-1.593.111-2.403s-.037-1.612-.111-2.403zm-2.229 13.143c.403-.878.018-1.917-.86-2.32-.878-.404-1.917-.019-2.321.859-.582 1.267-1.28 2.47-2.08 3.596-.56.788-.376 1.88.412 2.44s1.881.376 2.441-.412c.925-1.303 1.733-2.695 2.408-4.163zm-43.639-1.461c-.404-.878-1.443-1.263-2.321-.859-.878.403-1.263 1.442-.86 2.32.675 1.468 1.483 2.86 2.408 4.163.56.788 1.653.972 2.441.412.787-.56.972-1.652.412-2.44-.8-1.126-1.498-2.329-2.08-3.596zm7.354 8.87c-.788-.56-1.88-.376-2.44.412s-.376 1.881.412 2.441c1.303.925 2.695 1.733 4.163 2.408.878.403 1.917.018 2.32-.86.404-.878.019-1.917-.859-2.321-1.267-.582-2.47-1.28-3.596-2.08zm27.778 2.853c.788-.56.972-
1.653.412-2.441s-1.652-.972-2.44-.412c-1.126.8-2.329 1.498-3.596 2.08-.878.404-1.263 1.443-.859 2.321.403.878 1.442 1.263 2.32.86 1.468-.675 2.86-1.483 4.163-2.408zm-16.984 1.152c-.962-.089-1.814.619-1.904 1.581-.089.963.619 1.815 1.582 1.904.791.074 1.593.111 2.403.111s1.612-.037 2.403-.111c.963-.089 1.671-.941 1.582-1.904-.09-.962-.942-1.67-1.904-1.581-.685.064-1.379.096-2.081.096s-1.396-.032-2.081-.096z"/>
+ <path d="m750 150.25c-.878 0-1.753.015-2.624.045-.966.034-1.722.844-1.689 1.81.033.965.843 1.721 1.809 1.688.831-.029 1.666-.043 2.504-.043s1.673.014 2.504.043c.966.033 1.776-.723 1.809-1.688.033-.966-.723-1.776-1.689-1.81-.871-.03-1.746-.045-2.624-.045zm-11.449 4.415c.954-.154 1.603-1.053 1.449-2.007s-1.053-1.603-2.007-1.449c-1.735.281-3.45.621-5.143 1.018-.941.221-1.525 1.163-1.304 2.104s1.163 1.524 2.104 1.303c1.613-.378 3.248-.702 4.901-.969zm23.456-3.456c-.954-.154-1.853.495-2.007 1.449s.495 1.853 1.449 2.007c1.653.267 3.288.591 4.901.969.941.221 1.883-.362 2.104-1.303s-.363-1.883-1.304-2.104c-1.693-.397-3.408-.737-5.143-1.018zm-36.956 7.031c.905-.339 1.365-1.347 1.026-2.252-.338-.906-1.347-1.365-2.252-1.027-1.642.615-3.258 1.285-4.843 2.009-.879.401-1.266 1.439-.865 2.319.402.879 1.44 1.266 2.319.865 1.511-.69 3.05-1.329 4.615-1.914zm51.124-3.279c-.905-.338-1.914.121-2.252 1.027-.339.905.121 1.913 1.026 2.252 1.565.585 3.104 1.224 4.615 1.914.879.401 1.917.014 2.31
9-.865.401-.88.014-1.918-.865-2.319-1.585-.724-3.201-1.394-4.843-2.009zm-63.661 9.436c.821-.51 1.074-1.588.565-2.41-.509-.821-1.588-1.074-2.41-.565-1.487.922-2.94 1.895-4.355 2.916-.784.565-.961 1.659-.395 2.443.565.784 1.659.961 2.443.395 1.349-.973 2.734-1.9 4.152-2.779zm76.817-2.975c-.822-.509-1.901-.256-2.41.565-.509.822-.256 1.9.565 2.41 1.418.879 2.803 1.806 4.152 2.779.784.566 1.878.389 2.443-.395.566-.784.389-1.878-.395-2.443-1.415-1.021-2.868-1.994-4.355-2.916zm-87.915 11.461c.707-.659.745-1.767.086-2.474-.659-.706-1.766-.745-2.473-.086-1.278 1.192-2.514 2.428-3.706 3.706-.659.707-.62 1.814.086 2.473.707.659 1.815.621 2.474-.086 1.136-1.218 2.315-2.397 3.533-3.533zm99.555-2.56c-.707-.659-1.814-.62-2.473.086-.659.707-.621 1.815.086 2.474 1.218 1.136 2.397 2.315 3.533 3.533.659.707 1.767.745 2.474.086.706-.659.745-1.766.086-2.473-1.192-1.278-2.428-2.514-3.706-3.706zm-108.795 13.039c.566-.784.389-1.878-.395-2.443-.784-.566-1.878-.389-2.443.395-1.021 1.415-1.994 2.868-2.916 4.3
55-.509.822-.256 1.901.565 2.41.822.509 1.9.256 2.41-.565.879-1.418 1.806-2.803 2.779-4.152zm118.486-2.048c-.565-.784-1.659-.961-2.443-.395-.784.565-.961 1.659-.395 2.443.973 1.349 1.9 2.734 2.779 4.152.51.821 1.588 1.074 2.41.565.821-.509 1.074-1.588.565-2.41-.922-1.487-1.895-2.94-2.916-4.355zm-125.508 14.122c.401-.879.014-1.917-.865-2.319-.88-.401-1.918-.014-2.319.865-.724 1.585-1.394 3.201-2.009 4.843-.338.905.121 1.914 1.027 2.252.905.339 1.913-.121 2.252-1.026.585-1.565 1.224-3.104 1.914-4.615zm132.876-1.454c-.401-.879-1.439-1.266-2.319-.865-.879.402-1.266 1.44-.865 2.319.69 1.511 1.329 3.05 1.914 4.615.339.905 1.347 1.365 2.252 1.026.906-.338 1.365-1.347 1.027-2.252-.615-1.642-1.285-3.258-2.009-4.843zm-137.396 14.668c.221-.941-.362-1.883-1.303-2.104s-1.883.363-2.104 1.304c-.397 1.693-.737 3.408-1.018 5.143-.154.954.495 1.853 1.449 2.007s1.853-.495 2.007-1.449c.267-1.653.591-3.288.969-4.901zm142.139-.8c-.221-.941-1.163-1.525-2.104-1.304s-1.524 1.163-1.303 2.104c.378 1.613.702 3
.248.969 4.901.154.954 1.053 1.603 2.007 1.449s1.603-1.053 1.449-2.007c-.281-1.735-.621-3.45-1.018-5.143zm-143.98 14.646c.033-.966-.723-1.776-1.688-1.809-.966-.033-1.776.723-1.81 1.689-.03.871-.045 1.746-.045 2.624s.015 1.753.045 2.624c.034.966.844 1.722 1.81 1.689.965-.033 1.721-.843 1.688-1.809-.029-.831-.043-1.666-.043-2.504s.014-1.673.043-2.504zm145.912-.12c-.034-.966-.844-1.722-1.81-1.689-.965.033-1.721.843-1.688 1.809.029.831.043 1.666.043 2.504s-.014 1.673-.043 2.504c-.033.966.723 1.776 1.688 1.809.966.033 1.776-.723 1.81-1.689.03-.871.045-1.746.045-2.624s-.015-1.753-.045-2.624zm-145.04 14.073c-.154-.954-1.053-1.603-2.007-1.449s-1.603 1.053-1.449 2.007c.281 1.735.621 3.45 1.018 5.143.221.941 1.163 1.525 2.104 1.304s1.524-1.163 1.303-2.104c-.378-1.613-.702-3.248-.969-4.901zm144.126.558c.154-.954-.495-1.853-1.449-2.007s-1.853.495-2.007 1.449c-.267 1.653-.591 3.288-.969 4.901-.221.941.362 1.883 1.303 2.104s1.883-.363 2.104-1.304c.397-1.693.737-3.408 1.018-5.143zm-140.551 12.942c
-.339-.905-1.347-1.365-2.252-1.026-.906.338-1.365 1.347-1.027 2.252.615 1.642 1.285 3.258 2.009 4.843.401.879 1.439 1.266 2.319.865.879-.402 1.266-1.44.865-2.319-.69-1.511-1.329-3.05-1.914-4.615zm136.799 1.226c.338-.905-.121-1.914-1.027-2.252-.905-.339-1.913.121-2.252 1.026-.585 1.565-1.224 3.104-1.914 4.615-.401.879-.014 1.917.865 2.319.88.401 1.918.014 2.319-.865.724-1.585 1.394-3.201 2.009-4.843zm-130.642 11.311c-.51-.821-1.588-1.074-2.41-.565-.821.509-1.074 1.588-.565 2.41.922 1.487 1.895 2.94 2.916 4.355.565.784 1.659.961 2.443.395.784-.565.961-1.659.395-2.443-.973-1.349-1.9-2.734-2.779-4.152zm124.181 1.845c.509-.822.256-1.901-.565-2.41-.822-.509-1.9-.256-2.41.565-.879 1.418-1.806 2.803-2.779 4.152-.566.784-.389 1.878.395 2.443.784.566 1.878.389 2.443-.395 1.021-1.415 1.994-2.868 2.916-4.355zm-115.695 9.253c-.659-.707-1.767-.745-2.474-.086-.706.659-.745 1.766-.086 2.473 1.192 1.278 2.428 2.514 3.706 3.706.707.659 1.814.62 2.473-.086.659-.707.621-1.815-.086-2.474-1.218-1.136-2.3
97-2.315-3.533-3.533zm106.794 2.387c.659-.707.62-1.814-.086-2.473-.707-.659-1.815-.621-2.474.086-1.136 1.218-2.315 2.397-3.533 3.533-.707.659-.745 1.767-.086 2.474.659.706 1.766.745 2.473.086 1.278-1.192 2.514-2.428 3.706-3.706zm-96.315 6.853c-.784-.566-1.878-.389-2.443.395-.566.784-.389 1.878.395 2.443 1.415 1.021 2.868 1.994 4.355 2.916.822.509 1.901.256 2.41-.565.509-.822.256-1.9-.565-2.41-1.418-.879-2.803-1.806-4.152-2.779zm85.324 2.838c.784-.565.961-1.659.395-2.443-.565-.784-1.659-.961-2.443-.395-1.349.973-2.734 1.9-4.152 2.779-.821.51-1.074 1.588-.565 2.41.509.821 1.588 1.074 2.41.565 1.487-.922 2.94-1.895 4.355-2.916zm-73.25 4.184c-.879-.401-1.917-.014-2.319.865-.401.88-.014 1.918.865 2.319 1.585.724 3.201 1.394 4.843 2.009.905.338 1.914-.121 2.252-1.027.339-.905-.121-1.913-1.026-2.252-1.565-.585-3.104-1.224-4.615-1.914zm60.582 3.184c.879-.401 1.266-1.439.865-2.319-.402-.879-1.44-1.266-2.319-.865-1.511.69-3.05 1.329-4.615 1.914-.905.339-1.365 1.347-1.026 2.252.338.906 1.347 1
.365 2.252 1.027 1.642-.615 3.258-1.285 4.843-2.009zm-47.368 1.336c-.941-.221-1.883.362-2.104 1.303s.363 1.883 1.304 2.104c1.693.397 3.408.737 5.143 1.018.954.154 1.853-.495 2.007-1.449s-.495-1.853-1.449-2.007c-1.653-.267-3.288-.591-4.901-.969zm33.5 3.407c.941-.221 1.525-1.163 1.304-2.104s-1.163-1.524-2.104-1.303c-1.613.378-3.248.702-4.901.969-.954.154-1.603 1.053-1.449 2.007s1.053 1.603 2.007 1.449c1.735-.281 3.45-.621 5.143-1.018zm-19.654-1.566c-.966-.033-1.776.723-1.809 1.688-.033.966.723 1.776 1.689 1.81.871.03 1.746.045 2.624.045s1.753-.015 2.624-.045c.966-.034 1.722-.844 1.689-1.81-.033-.965-.843-1.721-1.809-1.688-.831.029-1.666.043-2.504.043s-1.673-.014-2.504-.043zm2.504-130.957c-.802 0-1.601.016-2.396.047-.965.038-1.717.852-1.679 1.818s.852 1.718 1.817 1.679c.749-.029 1.502-.044 2.258-.044s1.509.015 2.258.044c.966.039 1.779-.713 1.817-1.679s-.714-1.78-1.679-1.818c-.795-.031-1.594-.047-2.396-.047zm-10.317 4.444c.95-.176 1.578-1.09 1.402-2.04s-1.089-1.578-2.04-1.402c-1.579.293
-3.136.648-4.668 1.062-.933.252-1.485 1.213-1.233 2.146s1.213 1.485 2.146 1.233c1.442-.39 2.907-.724 4.393-.999zm21.272-3.442c-.951-.176-1.864.452-2.04 1.402s.452 1.864 1.402 2.04c1.486.275 2.951.609 4.393.999.933.252 1.894-.3 2.146-1.233s-.3-1.894-1.233-2.146c-1.532-.414-3.089-.769-4.668-1.062zm12.799 3.907c-.887-.385-1.917.022-2.302.909-.384.887.023 1.917.909 2.302 1.383.599 2.737 1.253 4.059 1.958.853.454 1.913.132 2.368-.721.454-.853.132-1.913-.721-2.368-1.405-.749-2.844-1.443-4.313-2.08zm-46.115 3.211c.886-.385 1.293-1.415.909-2.302-.385-.887-1.415-1.294-2.302-.909-1.469.637-2.908 1.331-4.313 2.08-.853.455-1.175 1.515-.721 2.368.455.853 1.515 1.175 2.368.721 1.322-.705 2.676-1.359 4.059-1.958zm-10.921 6.278c.779-.573.946-1.668.373-2.447-.572-.778-1.667-.945-2.446-.373-1.287.946-2.535 1.943-3.741 2.987-.731.633-.81 1.738-.177 2.469.632.73 1.738.81 2.468.177 1.136-.983 2.311-1.922 3.523-2.813zm68.637-2.82c-.779-.572-1.874-.405-2.446.373-.573.779-.406 1.874.373 2.447 1.212.891 2.3
87 1.83 3.523 2.813.73.633 1.836.553 2.468-.177.633-.731.554-1.836-.177-2.469-1.206-1.044-2.454-2.041-3.741-2.987zm-77.894 11.367c.633-.73.553-1.836-.177-2.468-.731-.633-1.836-.554-2.469.177-1.044 1.206-2.041 2.454-2.987 3.741-.572.779-.405 1.874.373 2.446.779.573 1.874.406 2.447-.373.891-1.212 1.83-2.387 2.813-3.523zm87.724-2.291c-.633-.731-1.738-.81-2.469-.177-.73.632-.81 1.738-.177 2.468.983 1.136 1.922 2.311 2.813 3.523.573.779 1.668.946 2.447.373.778-.572.945-1.667.373-2.446-.946-1.287-1.943-2.535-2.987-3.741zm7.576 11.029c-.455-.853-1.515-1.175-2.368-.721-.853.455-1.175 1.515-.721 2.368.705 1.322 1.359 2.676 1.958 4.059.385.886 1.415 1.293 2.302.909.887-.385 1.294-1.415.909-2.302-.637-1.469-1.331-2.908-2.08-4.313zm-102.433 1.647c.454-.853.132-1.913-.721-2.368-.853-.454-1.913-.132-2.368.721-.749 1.405-1.443 2.844-2.08 4.313-.385.887.022 1.917.909 2.302.887.384 1.917-.023 2.302-.909.599-1.383 1.253-2.737 1.958-4.059zm-4.635 11.71c.252-.933-.3-1.894-1.233-2.146s-1.894.3-2.146 1.2
33c-.414 1.532-.769 3.089-1.062 4.668-.176.951.452 1.864 1.402 2.04s1.864-.452 2.04-1.402c.275-1.486.609-2.951.999-4.393zm111.993-.913c-.252-.933-1.213-1.485-2.146-1.233s-1.485 1.213-1.233 2.146c.39 1.442.724 2.907.999 4.393.176.95 1.09 1.578 2.04 1.402s1.578-1.089 1.402-2.04c-.293-1.579-.648-3.136-1.062-4.668zm-113.892 13.365c.039-.966-.713-1.779-1.679-1.817s-1.78.714-1.818 1.679c-.031.795-.047 1.594-.047 2.396s.016 1.601.047 2.396c.038.965.852 1.717 1.818 1.679s1.718-.852 1.679-1.817c-.029-.749-.044-1.502-.044-2.258s.015-1.509.044-2.258zm115.909-.138c-.038-.965-.852-1.717-1.818-1.679s-1.718.852-1.679 1.817c.029.749.044 1.502.044 2.258s-.015 1.509-.044 2.258c-.039.966.713 1.779 1.679 1.817s1.78-.714 1.818-1.679c.031-.795.047-1.594.047-2.396s-.016-1.601-.047-2.396zm-115.009 12.713c-.176-.95-1.09-1.578-2.04-1.402s-1.578 1.089-1.402 2.04c.293 1.579.648 3.136 1.062 4.668.252.933 1.213 1.485 2.146 1.233s1.485-1.213 1.233-2.146c-.39-1.442-.724-2.907-.999-4.393zm114.054.638c.176-.951-.452
-1.864-1.402-2.04s-1.864.452-2.04 1.402c-.275 1.486-.609 2.951-.999 4.393-.252.933.3 1.894 1.233 2.146s1.894-.3 2.146-1.233c.414-1.532.769-3.089 1.062-4.668zm-110.378 11.406c-.385-.886-1.415-1.293-2.302-.909-.887.385-1.294 1.415-.909 2.302.637 1.469 1.331 2.908 2.08 4.313.455.853 1.515 1.175 2.368.721.853-.455 1.175-1.515.721-2.368-.705-1.322-1.359-2.676-1.958-4.059zm106.471 1.393c.385-.887-.022-1.917-.909-2.302-.887-.384-1.917.023-2.302.909-.599 1.383-1.253 2.737-1.958 4.059-.454.853-.132 1.913.721 2.368.853.454 1.913.132 2.368-.721.749-1.405 1.443-2.844 2.08-4.313zm-100.193 9.528c-.573-.779-1.668-.946-2.447-.373-.778.572-.945 1.667-.373 2.446.946 1.287 1.943 2.535 2.987 3.741.633.731 1.738.81 2.469.177.73-.632.81-1.738.177-2.468-.983-1.136-1.922-2.311-2.813-3.523zm93.524 2.073c.572-.779.405-1.874-.373-2.446-.779-.573-1.874-.406-2.447.373-.891 1.212-1.83 2.387-2.813 3.523-.633.73-.553 1.836.177 2.468.731.633 1.836.554 2.469-.177 1.044-1.206 2.041-2.454 2.987-3.741zm-84.977 7.184c-.
73-.633-1.836-.553-2.468.177-.633.731-.554 1.836.177 2.469 1.206 1.044 2.454 2.041 3.741 2.987.779.572 1.874.405 2.446-.373.573-.779.406-1.874-.373-2.447-1.212-.891-2.387-1.83-3.523-2.813zm75.901 2.646c.731-.633.81-1.738.177-2.469-.632-.73-1.738-.81-2.468-.177-1.136.983-2.311 1.922-3.523 2.813-.779.573-.946 1.668-.373 2.447.572.778 1.667.945 2.446.373 1.287-.946 2.535-1.943 3.741-2.987zm-65.516 4.487c-.853-.454-1.913-.132-2.368.721-.454.853-.132 1.913.721 2.368 1.405.749 2.844 1.443 4.313 2.08.887.385 1.917-.022 2.302-.909.384-.887-.023-1.917-.909-2.302-1.383-.599-2.737-1.253-4.059-1.958zm54.487 3.089c.853-.455 1.175-1.515.721-2.368-.455-.853-1.515-1.175-2.368-.721-1.322.705-2.676 1.359-4.059 1.958-.886.385-1.293 1.415-.909 2.302.385.887 1.415 1.294 2.302.909 1.469-.637 2.908-1.331 4.313-2.08zm-42.777 1.546c-.933-.252-1.894.3-2.146 1.233s.3 1.894 1.233 2.146c1.532.414 3.089.769 4.668 1.062.951.176 1.864-.452 2.04-1.402s-.452-1.864-1.402-2.04c-1.486-.275-2.951-.609-4.393-.999zm30.333
3.379c.933-.252 1.485-1.213 1.233-2.146s-1.213-1.485-2.146-1.233c-1.442.39-2.907.724-4.393.999-.95.176-1.578 1.09-1.402 2.04s1.089 1.578 2.04 1.402c1.579-.293 3.136-.648 4.668-1.062zm-17.881-1.48c-.966-.039-1.779.713-1.817 1.679s.714 1.78 1.679 1.818c.795.031 1.594.047 2.396.047s1.601-.016 2.396-.047c.965-.038 1.717-.852 1.679-1.818s-.852-1.718-1.817-1.679c-.749.029-1.502.044-2.258.044s-1.509-.015-2.258-.044zm-.139-98.89c.794-.044 1.593-.066 2.397-.066s1.603.022 2.397.066c.965.053 1.704.879 1.65 1.844-.053.965-.878 1.704-1.843 1.651-.73-.041-1.464-.061-2.204-.061s-1.474.02-2.204.061c-.965.053-1.79-.686-1.843-1.651-.054-.965.685-1.791 1.65-1.844zm-6.378 2.587c.247.934-.312 1.891-1.246 2.137-1.429.377-2.826.831-4.186 1.36-.901.35-1.915-.097-2.265-.998s.097-1.915.997-2.265c1.483-.576 3.005-1.071 4.563-1.481.934-.246 1.891.312 2.137 1.247zm17.55 0c.246-.935 1.203-1.493 2.137-1.247 1.558.41 3.08.905 4.563 1.481.901.35 1.347 1.364.997 2.265s-1.364 1.348-2.265.998c-1.36-.529-2.757-.983-4.
186-1.36-.934-.246-1.493-1.203-1.246-2.137zm-29.509 4.675c.525.812.291 1.895-.521 2.419-1.236.798-2.424 1.663-3.559 2.591-.749.611-1.851.5-2.463-.248-.611-.749-.5-1.851.248-2.463 1.236-1.01 2.53-1.952 3.876-2.82.812-.525 1.895-.291 2.419.521zm41.468 0c.524-.812 1.607-1.046 2.419-.521 1.346.868 2.64 1.81 3.876 2.82.748.612.859 1.714.248 2.463-.612.748-1.714.859-2.463.248-1.135-.928-2.323-1.793-3.559-2.591-.812-.524-1.046-1.607-.521-2.419zm-51.394 8.145c.748.612.859 1.714.248 2.463-.928 1.135-1.793 2.323-2.591 3.559-.524.812-1.607 1.046-2.419.521-.812-.524-1.046-1.607-.521-2.419.868-1.346 1.81-2.64 2.82-3.876.612-.748 1.714-.859 2.463-.248zm61.32 0c.749-.611 1.851-.5 2.463.248 1.01 1.236 1.952 2.53 2.82 3.876.525.812.291 1.895-.521 2.419-.812.525-1.895.291-2.419-.521-.798-1.236-1.663-2.424-2.591-3.559-.611-.749-.5-1.851.248-2.463zm-68.258 10.805c.901.35 1.348 1.364.998 2.265-.529 1.36-.983 2.757-1.36 4.186-.246.934-1.203 1.493-2.137 1.246-.935-.246-1.493-1.203-1.247-2.137.41-1.558.905
-3.08 1.481-4.563.35-.9 1.364-1.347 2.265-.997zm75.196 0c.901-.35 1.915.097 2.265.997.576 1.483 1.071 3.005 1.481 4.563.246.934-.312 1.891-1.247 2.137-.934.247-1.891-.312-2.137-1.246-.377-1.429-.831-2.826-1.36-4.186-.35-.901.097-1.915.998-2.265zm-78.438 12.425c.965.053 1.704.878 1.651 1.843-.041.73-.061 1.464-.061 2.204s.02 1.474.061 2.204c.053.965-.686 1.79-1.651 1.843-.965.054-1.791-.685-1.844-1.65-.044-.794-.066-1.593-.066-2.397s.022-1.603.066-2.397c.053-.965.879-1.704 1.844-1.65zm81.68 0c.965-.054 1.791.685 1.844 1.65.044.794.066 1.593.066 2.397s-.022 1.603-.066 2.397c-.053.965-.879 1.704-1.844 1.65-.965-.053-1.704-.878-1.651-1.843.041-.73.061-1.464.061-2.204s-.02-1.474-.061-2.204c-.053-.965.686-1.79 1.651-1.843zm-80.937 12.822c.934-.247 1.891.312 2.137 1.246.377 1.429.831 2.826 1.36 4.186.35.901-.097 1.915-.998 2.265s-1.915-.097-2.265-.997c-.576-1.483-1.071-3.005-1.481-4.563-.246-.934.312-1.891 1.247-2.137zm80.194 0c.935.246 1.493 1.203 1.247 2.137-.41 1.558-.905 3.08-1.481 4.5
63-.35.901-1.364 1.347-2.265.997s-1.348-1.364-.998-2.265c.529-1.36.983-2.757 1.36-4.186.246-.934 1.203-1.493 2.137-1.246zm-75.519 11.959c.812-.525 1.895-.291 2.419.521.798 1.236 1.663 2.424 2.591 3.559.611.749.5 1.851-.248 2.463-.749.611-1.851.5-2.463-.248-1.01-1.236-1.952-2.53-2.82-3.876-.525-.812-.291-1.895.521-2.419zm70.844 0c.812.524 1.046 1.607.521 2.419-.868 1.346-1.81 2.64-2.82 3.876-.612.748-1.714.859-2.463.248-.748-.612-.859-1.714-.248-2.463.928-1.135 1.793-2.323 2.591-3.559.524-.812 1.607-1.046 2.419-.521zm-62.699 9.926c.612-.748 1.714-.859 2.463-.248 1.135.928 2.323 1.793 3.559 2.591.812.524 1.046 1.607.521 2.419-.524.812-1.607 1.046-2.419.521-1.346-.868-2.64-1.81-3.876-2.82-.748-.612-.859-1.714-.248-2.463zm54.554 0c.611.749.5 1.851-.248 2.463-1.236 1.01-2.53 1.952-3.876 2.82-.812.525-1.895.291-2.419-.521-.525-.812-.291-1.895.521-2.419 1.236-.798 2.424-1.663 3.559-2.591.749-.611 1.851-.5 2.463.248zm-43.749 6.938c.35-.901 1.364-1.348 2.265-.998 1.36.529 2.757.983 4.186 1.3
6.934.246 1.493 1.203 1.246 2.137-.246.935-1.203 1.493-2.137 1.247-1.558-.41-3.08-.905-4.563-1.481-.9-.35-1.347-1.364-.997-2.265zm32.944 0c.35.901-.097 1.915-.997 2.265-1.483.576-3.005 1.071-4.563 1.481-.934.246-1.891-.312-2.137-1.247-.247-.934.312-1.891 1.246-2.137 1.429-.377 2.826-.831 4.186-1.36.901-.35 1.915.097 2.265.998zm-20.519 3.242c.053-.965.878-1.704 1.843-1.651.73.041 1.464.061 2.204.061s1.474-.02 2.204-.061c.965-.053 1.79.686 1.843 1.651.054.965-.685 1.791-1.65 1.844-.794.044-1.593.066-2.397.066s-1.603-.022-2.397-.066c-.965-.053-1.704-.879-1.65-1.844zm4.047-66.59c-.81 0-1.612.037-2.403.111-.963.089-1.671.941-1.582 1.904.09.962.942 1.67 1.904 1.581.685-.064 1.379-.096 2.081-.096s1.396.032 2.081.096c.962.089 1.814-.619 1.904-1.581.089-.963-.619-1.815-1.582-1.904-.791-.074-1.593-.111-2.403-.111zm10.74 2.34c-.878-.403-1.917-.018-2.32.86-.404.878-.019 1.917.859 2.321 1.267.582 2.47 1.28 3.596 2.08.788.56 1.88.375 2.44-.412.56-.788.376-1.881-.412-2.441-1.303-.925-2.695-1.733-4
.163-2.408zm-20.019 3.181c.878-.404 1.263-1.443.859-2.321-.403-.878-1.442-1.263-2.32-.86-1.468.675-2.86 1.483-4.163 2.408-.788.56-.972 1.653-.412 2.441.56.787 1.652.972 2.44.412 1.126-.8 2.329-1.498 3.596-2.08zm30.281 5.326c-.56-.788-1.653-.972-2.441-.412s-.972 1.652-.412 2.44c.8 1.126 1.498 2.329 2.08 3.596.404.878 1.443 1.263 2.321.859.878-.403 1.263-1.442.86-2.32-.675-1.468-1.483-2.86-2.408-4.163zm-39.151 2.028c.56-.788.375-1.88-.412-2.44-.788-.56-1.881-.376-2.441.412-.925 1.303-1.733 2.695-2.408 4.163-.403.878-.018 1.917.86 2.32.878.404 1.917.019 2.321-.859.582-1.267 1.28-2.47 2.08-3.596zm-4.005 10.794c.089-.962-.619-1.814-1.581-1.904-.963-.089-1.815.619-1.904 1.582-.074.791-.111 1.593-.111 2.403s.037 1.612.111 2.403c.089.963.941 1.671 1.904 1.582.962-.09 1.67-.942 1.581-1.904-.064-.685-.096-1.379-.096-2.081s.032-1.396.096-2.081zm47.793-.322c-.089-.963-.941-1.671-1.904-1.582-.962.09-1.67.942-1.581 1.904.064.685.096 1.379.096 2.081s-.032 1.396-.096 2.081c-.089.962.619 1.814 1.581
1.904.963.089 1.815-.619 1.904-1.582.074-.791.111-1.593.111-2.403s-.037-1.612-.111-2.403zm-2.229 13.143c.403-.878.018-1.917-.86-2.32-.878-.404-1.917-.019-2.321.859-.582 1.267-1.28 2.47-2.08 3.596-.56.788-.376 1.88.412 2.44s1.881.376 2.441-.412c.925-1.303 1.733-2.695 2.408-4.163zm-43.639-1.461c-.404-.878-1.443-1.263-2.321-.859-.878.403-1.263 1.442-.86 2.32.675 1.468 1.483 2.86 2.408 4.163.56.788 1.653.972 2.441.412.787-.56.972-1.652.412-2.44-.8-1.126-1.498-2.329-2.08-3.596zm7.354 8.87c-.788-.56-1.88-.376-2.44.412s-.376 1.881.412 2.441c1.303.925 2.695 1.733 4.163 2.408.878.403 1.917.018 2.32-.86.404-.878.019-1.917-.859-2.321-1.267-.582-2.47-1.28-3.596-2.08zm27.778 2.853c.788-.56.972-1.653.412-2.441s-1.652-.972-2.44-.412c-1.126.8-2.329 1.498-3.596 2.08-.878.404-1.263 1.443-.859 2.321.403.878 1.442 1.263 2.32.86 1.468-.675 2.86-1.483 4.163-2.408zm-16.984 1.152c-.962-.089-1.814.619-1.904 1.581-.089.963.619 1.815 1.582 1.904.791.074 1.593.111 2.403.111s1.612-.037 2.403-.111c.963-.089 1.6
71-.941 1.582-1.904-.09-.962-.942-1.67-1.904-1.581-.685.064-1.379.096-2.081.096s-1.396-.032-2.081-.096z"/>
+ <path d="m528.75 225c0-39.35 31.9-71.25 71.25-71.25s71.25 31.9 71.25 71.25-31.9 71.25-71.25 71.25-71.25-31.9-71.25-71.25zm71.25-74.75c-41.283 0-74.75 33.467-74.75 74.75s33.467 74.75 74.75 74.75 74.75-33.467 74.75-74.75-33.467-74.75-74.75-74.75zm-55.25 74.75c0-30.514 24.736-55.25 55.25-55.25s55.25 24.736 55.25 55.25-24.736 55.25-55.25 55.25-55.25-24.736-55.25-55.25zm55.25-58.75c-32.447 0-58.75 26.303-58.75 58.75s26.303 58.75 58.75 58.75 58.75-26.303 58.75-58.75-26.303-58.75-58.75-58.75zm0 19.5c-21.677 0-39.25 17.573-39.25 39.25s17.573 39.25 39.25 39.25 39.25-17.573 39.25-39.25-17.573-39.25-39.25-39.25zm-42.75 39.25c0-23.61 19.14-42.75 42.75-42.75s42.75 19.14 42.75 42.75-19.14 42.75-42.75 42.75-42.75-19.14-42.75-42.75zm20.5 0c0-12.288 9.962-22.25 22.25-22.25s22.25 9.962 22.25 22.25-9.962 22.25-22.25 22.25-22.25-9.962-22.25-22.25zm22.25-25.75c-14.221 0-25.75 11.529-25.75 25.75s11.529 25.75 25.75 25.75 25.75-11.529 25.75-25.75-11.529-25.75-25.75-25.75z"/>
+ </g>
+ </g>
+</svg>
\ No newline at end of file
diff --git a/browser/themes/shared/urlbar-searchbar.inc.css b/browser/themes/shared/urlbar-searchbar.inc.css
index 0158597991ec..d7dc7df17f19 100644
--- a/browser/themes/shared/urlbar-searchbar.inc.css
+++ b/browser/themes/shared/urlbar-searchbar.inc.css
@@ -747,3 +747,5 @@ moz-input-box > menupopup .context-menu-add-engine > .menu-iconic-left::after {
}
%include ../../components/onionservices/content/onionlocation-urlbar.css
+%include ../../components/torconnect/content/torconnect-urlbar.css
+
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp
index b00399e2eccb..7e103e2705d1 100644
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -17143,9 +17143,56 @@ void Document::RemoveToplevelLoadingDocument(Document* aDoc) {
StylePrefersColorScheme Document::PrefersColorScheme(
IgnoreRFP aIgnoreRFP) const {
+
+ // tor-browser#27476
+ // should this document ignore resist finger-printing settings with regards to
+ // setting the color scheme
+ // currently only enabled for about:torconnect but we could expand to other non-
+ // SystemPrincipal pages if we wish
+ const auto documentUsesPreferredColorScheme = [](auto const* constDocument) -> bool {
+ if (auto* document = const_cast<Document*>(constDocument); document != nullptr) {
+ auto uri = document->GetDocBaseURI();
+
+ // try and extract out our prepath and filepath portions of the uri to C-strings
+ nsAutoCString prePathStr, filePathStr;
+ if(NS_FAILED(uri->GetPrePath(prePathStr)) ||
+ NS_FAILED(uri->GetFilePath(filePathStr))) {
+ return false;
+ }
+
+ // stick them in string view for easy comparisons
+ std::string_view prePath(prePathStr.get(), prePathStr.Length()),
+ filePath(filePathStr.get(), filePathStr.Length());
+
+ // these about URIs will have the user's preferred color scheme exposed to them
+ // we can place other URIs here in the future if we wish
+ // see nsIURI.idl for URI part definitions
+ constexpr struct {
+ std::string_view prePath;
+ std::string_view filePath;
+ } allowedURIs[] = {
+ { "about:", "torconnect" },
+ };
+
+ // check each uri in the allow list against this document's uri
+ // verify the prepath and the file path match
+ for(auto const& uri : allowedURIs) {
+ if (prePath == uri.prePath &&
+ filePath == uri.filePath) {
+ // positive match means we can apply dark-mode to the page
+ return true;
+ }
+ }
+ }
+
+ // do not allow if no match or other error
+ return false;
+ };
+
if (aIgnoreRFP == IgnoreRFP::No &&
- nsContentUtils::ShouldResistFingerprinting(this)) {
- return StylePrefersColorScheme::Light;
+ nsContentUtils::ShouldResistFingerprinting(this) &&
+ !documentUsesPreferredColorScheme(this)) {
+ return StylePrefersColorScheme::Light;
}
if (auto* bc = GetBrowsingContext()) {
diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp
index 4da5365f214d..e981573e9822 100644
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -6213,6 +6213,8 @@ void nsGlobalWindowOuter::CloseOuter(bool aTrustedCaller) {
NS_ENSURE_SUCCESS_VOID(rv);
if (!StringBeginsWith(url, u"about:neterror"_ns) &&
+ // we want about:torconnect pages to be able to close themselves after bootstrap
+ !StringBeginsWith(url, u"about:torconnect"_ns) &&
!mBrowsingContext->HadOriginalOpener() && !aTrustedCaller &&
!IsOnlyTopLevelDocumentInSHistory()) {
bool allowClose =
diff --git a/toolkit/components/processsingleton/MainProcessSingleton.jsm b/toolkit/components/processsingleton/MainProcessSingleton.jsm
index ecdbf2a01d99..62afa98e1ffc 100644
--- a/toolkit/components/processsingleton/MainProcessSingleton.jsm
+++ b/toolkit/components/processsingleton/MainProcessSingleton.jsm
@@ -24,6 +24,11 @@ MainProcessSingleton.prototype = {
null
);
+ ChromeUtils.import(
+ "resource:///modules/TorConnect.jsm",
+ null
+ );
+
Services.ppmm.loadProcessScript(
"chrome://global/content/process-content.js",
true
diff --git a/toolkit/modules/AsyncPrefs.jsm b/toolkit/modules/AsyncPrefs.jsm
index 2834c484c919..f7d867e47dc0 100644
--- a/toolkit/modules/AsyncPrefs.jsm
+++ b/toolkit/modules/AsyncPrefs.jsm
@@ -20,6 +20,7 @@ const kAllowedPrefs = new Set([
"browser.contentblocking.report.hide_vpn_banner",
"browser.contentblocking.report.show_mobile_app",
+ "extensions.torlauncher.quickstart",
"narrate.rate",
"narrate.voice",
diff --git a/toolkit/modules/RemotePageAccessManager.jsm b/toolkit/modules/RemotePageAccessManager.jsm
index c12e71ac4d42..5125203866b8 100644
--- a/toolkit/modules/RemotePageAccessManager.jsm
+++ b/toolkit/modules/RemotePageAccessManager.jsm
@@ -103,6 +103,7 @@ let RemotePageAccessManager = {
RPMGetInnerMostURI: ["*"],
RPMGetHttpResponseHeader: ["*"],
RPMGetTorStrings: ["*"],
+ RPMSendQuery: ["ShouldShowTorConnect"],
},
"about:plugins": {
RPMSendQuery: ["RequestPlugins"],
@@ -219,6 +220,21 @@ let RemotePageAccessManager = {
"FetchUpdateData",
],
},
+ "about:torconnect": {
+ RPMAddMessageListener: [
+ "torconnect:state-change",
+ ],
+ RPMSendAsyncMessage: [
+ "torconnect:open-tor-preferences",
+ "torconnect:begin-bootstrap",
+ "torconnect:cancel-bootstrap",
+ "torconnect:set-quickstart",
+ ],
+ RPMSendQuery: [
+ "torconnect:get-init-args",
+ "torconnect:copy-tor-logs",
+ ],
+ },
},
/**
diff --git a/toolkit/mozapps/update/UpdateService.jsm b/toolkit/mozapps/update/UpdateService.jsm
index f4f925992027..f0a48d021638 100644
--- a/toolkit/mozapps/update/UpdateService.jsm
+++ b/toolkit/mozapps/update/UpdateService.jsm
@@ -12,6 +12,17 @@ const { AppConstants } = ChromeUtils.import(
const { AUSTLMY } = ChromeUtils.import(
"resource://gre/modules/UpdateTelemetry.jsm"
);
+
+const { TorProtocolService } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+
+function _shouldRegisterBootstrapObserver(errorCode) {
+ return errorCode == PROXY_SERVER_CONNECTION_REFUSED &&
+ !TorProtocolService.isBootstrapDone() &&
+ TorProtocolService.ownsTorDaemon;
+};
+
const {
Bits,
BitsRequest,
@@ -232,6 +243,7 @@ const SERVICE_ERRORS = [
// Custom update error codes
const BACKGROUNDCHECK_MULTIPLE_FAILURES = 110;
const NETWORK_ERROR_OFFLINE = 111;
+const PROXY_SERVER_CONNECTION_REFUSED = 2152398920;
// Error codes should be < 1000. Errors above 1000 represent http status codes
const HTTP_ERROR_OFFSET = 1000;
@@ -2676,6 +2688,9 @@ UpdateService.prototype = {
case "network:offline-status-changed":
this._offlineStatusChanged(data);
break;
+ case "torconnect:bootstrap-complete":
+ this._bootstrapComplete();
+ break;
case "nsPref:changed":
if (data == PREF_APP_UPDATE_LOG || data == PREF_APP_UPDATE_LOG_FILE) {
gLogEnabled; // Assigning this before it is lazy-loaded is an error.
@@ -3169,6 +3184,35 @@ UpdateService.prototype = {
this._attemptResume();
},
+ _registerBootstrapObserver: function AUS__registerBootstrapObserver() {
+ if (this._registeredBootstrapObserver) {
+ LOG(
+ "UpdateService:_registerBootstrapObserver - observer already registered"
+ );
+ return;
+ }
+
+ LOG(
+ "UpdateService:_registerBootstrapObserver - waiting for tor bootstrap to " +
+ "be complete, then forcing another check"
+ );
+
+ Services.obs.addObserver(this, "torconnect:bootstrap-complete");
+ this._registeredBootstrapObserver = true;
+ },
+
+ _bootstrapComplete: function AUS__bootstrapComplete() {
+ Services.obs.removeObserver(this, "torconnect:bootstrap-complete");
+ this._registeredBootstrapObserver = false;
+
+ LOG(
+ "UpdateService:_bootstrapComplete - bootstrapping complete, forcing " +
+ "another background check"
+ );
+
+ this._attemptResume();
+ },
+
onCheckComplete: function AUS_onCheckComplete(request, updates) {
this._selectAndInstallUpdate(updates);
},
@@ -3188,6 +3232,11 @@ UpdateService.prototype = {
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_OFFLINE);
}
return;
+ } else if (_shouldRegisterBootstrapObserver(update.errorCode)) {
+ // Register boostrap observer to try again, but only when we own the
+ // tor process.
+ this._registerBootstrapObserver();
+ return;
}
// Send the error code to telemetry
@@ -6011,6 +6060,7 @@ Downloader.prototype = {
var state = this._patch.state;
var shouldShowPrompt = false;
var shouldRegisterOnlineObserver = false;
+ var shouldRegisterBootstrapObserver = false;
var shouldRetrySoon = false;
var deleteActiveUpdate = false;
let migratedToReadyUpdate = false;
@@ -6129,7 +6179,18 @@ Downloader.prototype = {
);
shouldRegisterOnlineObserver = true;
deleteActiveUpdate = false;
-
+ } else if(_shouldRegisterBootstrapObserver(status)) {
+ // Register a bootstrap observer to try again.
+ // The bootstrap observer will continue the incremental download by
+ // calling downloadUpdate on the active update which continues
+ // downloading the file from where it was.
+ LOG("Downloader:onStopRequest - not bootstrapped, register bootstrap observer: true");
+ AUSTLMY.pingDownloadCode(
+ this.isCompleteUpdate,
+ AUSTLMY.DWNLD_RETRY_OFFLINE
+ );
+ shouldRegisterBootstrapObserver = true;
+ deleteActiveUpdate = false;
// Each of NS_ERROR_NET_TIMEOUT, ERROR_CONNECTION_REFUSED,
// NS_ERROR_NET_RESET and NS_ERROR_DOCUMENT_NOT_CACHED can be returned
// when disconnecting the internet while a download of a MAR is in
@@ -6251,7 +6312,7 @@ Downloader.prototype = {
// Only notify listeners about the stopped state if we
// aren't handling an internal retry.
- if (!shouldRetrySoon && !shouldRegisterOnlineObserver) {
+ if (!shouldRetrySoon && !shouldRegisterOnlineObserver && !shouldRegisterBootstrapObserver) {
this.updateService.forEachDownloadListener(listener => {
listener.onStopRequest(request, status);
});
@@ -6437,6 +6498,9 @@ Downloader.prototype = {
if (shouldRegisterOnlineObserver) {
LOG("Downloader:onStopRequest - Registering online observer");
this.updateService._registerOnlineObserver();
+ } else if (shouldRegisterBootstrapObserver) {
+ LOG("Downloader:onStopRequest - Registering bootstrap observer");
+ this.updateService._registerBootstrapObserver();
} else if (shouldRetrySoon) {
LOG("Downloader:onStopRequest - Retrying soon");
this.updateService._consecutiveSocketErrors++;
diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js
index 2ff107b553b2..f8fa83574df7 100644
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js
@@ -70,6 +70,10 @@ function getGlobalScriptIncludes(scriptPath) {
let match = line.match(globalScriptsRegExp);
if (match) {
let sourceFile = match[1]
+ .replace(
+ "chrome://browser/content/torconnect/",
+ "browser/components/torconnect/content/"
+ )
.replace(
"chrome://browser/content/search/",
"browser/components/search/content/"
1
0
[tor-browser/tor-browser-91.4.0esr-11.0-1] Bug 40597: Implement TorSettings module
by sysrqb@torproject.org 02 Dec '21
by sysrqb@torproject.org 02 Dec '21
02 Dec '21
commit dd142c5a83dbee21d4e060bad404e8f20a9e30ab
Author: Richard Pospesel <richard(a)torproject.org>
Date: Fri Aug 6 16:39:03 2021 +0200
Bug 40597: Implement TorSettings module
- migrated in-page settings read/write implementation from about:preferences#tor
to the TorSettings module
- TorSettings initially loads settings from the tor daemon, and saves them to
firefox prefs
- TorSettings notifies observers when a setting has changed; currently only
QuickStart notification is implemented for parity with previous preference
notify logic in about:torconnect and about:preferences#tor
- about:preferences#tor, and about:torconnect now read and write settings
thorugh the TorSettings module
- all tor settings live in the torbrowser.settings.* preference branch
- removed unused pref modify permission for about:torconnect content page from
AsyncPrefs.jsm
---
browser/components/torconnect/TorConnectParent.jsm | 25 +-
.../torpreferences/content/parseFunctions.jsm | 89 ---
.../torpreferences/content/torBridgeSettings.jsm | 325 --------
.../torpreferences/content/torFirewallSettings.jsm | 72 --
.../components/torpreferences/content/torPane.js | 301 ++++----
.../torpreferences/content/torProxySettings.jsm | 245 -------
browser/components/torpreferences/jar.mn | 12 +-
browser/modules/TorConnect.jsm | 47 +-
browser/modules/TorSettings.jsm | 814 +++++++++++++++++++++
browser/modules/moz.build | 1 +
.../processsingleton/MainProcessSingleton.jsm | 5 +
toolkit/modules/AsyncPrefs.jsm | 1 -
12 files changed, 989 insertions(+), 948 deletions(-)
diff --git a/browser/components/torconnect/TorConnectParent.jsm b/browser/components/torconnect/TorConnectParent.jsm
index 526c588a423e..2fbc2a5c7c7c 100644
--- a/browser/components/torconnect/TorConnectParent.jsm
+++ b/browser/components/torconnect/TorConnectParent.jsm
@@ -7,10 +7,9 @@ const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
const { TorConnect, TorConnectTopics, TorConnectState } = ChromeUtils.import(
"resource:///modules/TorConnect.jsm"
);
-
-const TorLauncherPrefs = Object.freeze({
- quickstart: "extensions.torlauncher.quickstart",
-});
+const { TorSettings, TorSettingsTopics, TorSettingsData } = ChromeUtils.import(
+ "resource:///modules/TorSettings.jsm"
+);
/*
This object is basically a marshalling interface between the TorConnect module
@@ -31,7 +30,7 @@ class TorConnectParent extends JSWindowActorParent {
BootstrapProgress: TorConnect.bootstrapProgress,
BootstrapStatus: TorConnect.bootstrapStatus,
ShowCopyLog: TorConnect.logHasWarningOrError,
- QuickStartEnabled: Services.prefs.getBoolPref(TorLauncherPrefs.quickstart, false),
+ QuickStartEnabled: TorSettings.quickstart.enabled,
};
// JSWindowActiveParent derived objects cannot observe directly, so create a member
@@ -78,9 +77,12 @@ class TorConnectParent extends JSWindowActorParent {
// TODO: handle
break;
}
- case "nsPref:changed": {
- if (aData === TorLauncherPrefs.quickstart) {
- self.state.QuickStartEnabled = Services.prefs.getBoolPref(TorLauncherPrefs.quickstart);
+ case TorSettingsTopics.SettingChanged:{
+ if (aData === TorSettingsData.QuickStartEnabled) {
+ self.state.QuickStartEnabled = obj.value;
+ } else {
+ // this isn't a setting torconnect cares about
+ return;
}
break;
}
@@ -98,7 +100,7 @@ class TorConnectParent extends JSWindowActorParent {
const topic = TorConnectTopics[key];
Services.obs.addObserver(this.torConnectObserver, topic);
}
- Services.prefs.addObserver(TorLauncherPrefs.quickstart, this.torConnectObserver);
+ Services.obs.addObserver(this.torConnectObserver, TorSettingsTopics.SettingChanged);
}
willDestroy() {
@@ -107,13 +109,14 @@ class TorConnectParent extends JSWindowActorParent {
const topic = TorConnectTopics[key];
Services.obs.removeObserver(this.torConnectObserver, topic);
}
- Services.prefs.removeObserver(TorLauncherPrefs.quickstart, this.torConnectObserver);
+ Services.obs.removeObserver(this.torConnectObserver, TorSettingsTopics.SettingChanged);
}
receiveMessage(message) {
switch (message.name) {
case "torconnect:set-quickstart":
- Services.prefs.setBoolPref(TorLauncherPrefs.quickstart, message.data);
+ TorSettings.quickstart.enabled = message.data;
+ TorSettings.saveToPrefs().applySettings();
break;
case "torconnect:open-tor-preferences":
TorConnect.openTorPreferences();
diff --git a/browser/components/torpreferences/content/parseFunctions.jsm b/browser/components/torpreferences/content/parseFunctions.jsm
deleted file mode 100644
index 954759de63a5..000000000000
--- a/browser/components/torpreferences/content/parseFunctions.jsm
+++ /dev/null
@@ -1,89 +0,0 @@
-"use strict";
-
-var EXPORTED_SYMBOLS = [
- "parsePort",
- "parseAddrPort",
- "parseUsernamePassword",
- "parseAddrPortList",
- "parseBridgeStrings",
- "parsePortList",
-];
-
-// expects a string representation of an integer from 1 to 65535
-let parsePort = function(aPort) {
- // ensure port string is a valid positive integer
- const validIntRegex = /^[0-9]+$/;
- if (!validIntRegex.test(aPort)) {
- throw new Error(`Invalid PORT string : '${aPort}'`);
- }
-
- // ensure port value is on valid range
- let port = Number.parseInt(aPort);
- if (port < 1 || port > 65535) {
- throw new Error(
- `Invalid PORT value, needs to be on range [1,65535] : '${port}'`
- );
- }
-
- return port;
-};
-// expects a string in the format: "ADDRESS:PORT"
-let parseAddrPort = function(aAddrColonPort) {
- let tokens = aAddrColonPort.split(":");
- if (tokens.length != 2) {
- throw new Error(`Invalid ADDRESS:PORT string : '${aAddrColonPort}'`);
- }
- let address = tokens[0];
- let port = parsePort(tokens[1]);
- return [address, port];
-};
-
-// expects a string in the format: "USERNAME:PASSWORD"
-// split on the first colon and any subsequent go into password
-let parseUsernamePassword = function(aUsernameColonPassword) {
- let colonIndex = aUsernameColonPassword.indexOf(":");
- if (colonIndex < 0) {
- // we don't log the contents of the potentially password containing string
- throw new Error("Invalid USERNAME:PASSWORD string");
- }
-
- let username = aUsernameColonPassword.substring(0, colonIndex);
- let password = aUsernameColonPassword.substring(colonIndex + 1);
-
- return [username, password];
-};
-
-// expects a string in the format: ADDRESS:PORT,ADDRESS:PORT,...
-// returns array of ports (as ints)
-let parseAddrPortList = function(aAddrPortList) {
- let addrPorts = aAddrPortList.split(",");
- // parse ADDRESS:PORT string and only keep the port (second element in returned array)
- let retval = addrPorts.map(addrPort => parseAddrPort(addrPort)[1]);
- return retval;
-};
-
-// expects a '/n' or '/r/n' delimited bridge string, which we split and trim
-// each bridge string can also optionally have 'bridge' at the beginning ie:
-// bridge $(type) $(address):$(port) $(certificate)
-// we strip out the 'bridge' prefix here
-let parseBridgeStrings = function(aBridgeStrings) {
-
- // replace carriage returns ('\r') with new lines ('\n')
- aBridgeStrings = aBridgeStrings.replace(/\r/g, "\n");
- // then replace contiguous new lines ('\n') with a single one
- aBridgeStrings = aBridgeStrings.replace(/[\n]+/g, "\n");
-
- // split on the newline and for each bridge string: trim, remove starting 'bridge' string
- // finally discard entries that are empty strings; empty strings could occur if we receive
- // a new line containing only whitespace
- let splitStrings = aBridgeStrings.split("\n");
- return splitStrings.map(val => val.trim().replace(/^bridge\s+/i, ""))
- .filter(bridgeString => bridgeString != "");
-};
-
-// expecting a ',' delimited list of ints with possible white space between
-// returns an array of ints
-let parsePortList = function(aPortListString) {
- let splitStrings = aPortListString.split(",");
- return splitStrings.map(val => parsePort(val.trim()));
-};
diff --git a/browser/components/torpreferences/content/torBridgeSettings.jsm b/browser/components/torpreferences/content/torBridgeSettings.jsm
deleted file mode 100644
index ceb61d3ec972..000000000000
--- a/browser/components/torpreferences/content/torBridgeSettings.jsm
+++ /dev/null
@@ -1,325 +0,0 @@
-"use strict";
-
-var EXPORTED_SYMBOLS = [
- "TorBridgeSource",
- "TorBridgeSettings",
- "makeTorBridgeSettingsNone",
- "makeTorBridgeSettingsBuiltin",
- "makeTorBridgeSettingsBridgeDB",
- "makeTorBridgeSettingsUserProvided",
-];
-
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { TorProtocolService } = ChromeUtils.import(
- "resource:///modules/TorProtocolService.jsm"
-);
-const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
-
-const TorBridgeSource = {
- NONE: "NONE",
- BUILTIN: "BUILTIN",
- BRIDGEDB: "BRIDGEDB",
- USERPROVIDED: "USERPROVIDED",
-};
-
-class TorBridgeSettings {
- constructor() {
- this._bridgeSource = TorBridgeSource.NONE;
- this._selectedDefaultBridgeType = null;
- this._bridgeStrings = [];
- }
-
- get selectedDefaultBridgeType() {
- if (this._bridgeSource == TorBridgeSource.BUILTIN) {
- return this._selectedDefaultBridgeType;
- }
- return undefined;
- }
-
- get bridgeSource() {
- return this._bridgeSource;
- }
-
- // for display
- get bridgeStrings() {
- return this._bridgeStrings.join("\n");
- }
-
- // raw
- get bridgeStringsArray() {
- return this._bridgeStrings;
- }
-
- static get defaultBridgeTypes() {
- if (TorBridgeSettings._defaultBridgeTypes) {
- return TorBridgeSettings._defaultBridgeTypes;
- }
-
- let bridgeListBranch = Services.prefs.getBranch(
- TorStrings.preferenceBranches.defaultBridge
- );
- let bridgePrefs = bridgeListBranch.getChildList("", {});
-
- // an unordered set for shoving bridge types into
- let bridgeTypes = new Set();
- // look for keys ending in ".N" and treat string before that as the bridge type
- const pattern = /\.[0-9]+$/;
- for (const key of bridgePrefs) {
- const offset = key.search(pattern);
- if (offset != -1) {
- const bt = key.substring(0, offset);
- bridgeTypes.add(bt);
- }
- }
-
- // recommended bridge type goes first in the list
- let recommendedBridgeType = Services.prefs.getCharPref(
- TorStrings.preferenceKeys.recommendedBridgeType,
- null
- );
-
- let retval = [];
- if (recommendedBridgeType && bridgeTypes.has(recommendedBridgeType)) {
- retval.push(recommendedBridgeType);
- }
-
- for (const bridgeType of bridgeTypes.values()) {
- if (bridgeType != recommendedBridgeType) {
- retval.push(bridgeType);
- }
- }
-
- // cache off
- TorBridgeSettings._defaultBridgeTypes = retval;
- return retval;
- }
-
- _readDefaultBridges(aBridgeType) {
- let bridgeBranch = Services.prefs.getBranch(
- TorStrings.preferenceBranches.defaultBridge
- );
- let bridgeBranchPrefs = bridgeBranch.getChildList("", {});
-
- let retval = [];
-
- // regex matches against strings ending in ".N" where N is a positive integer
- let pattern = /\.[0-9]+$/;
- for (const key of bridgeBranchPrefs) {
- // verify the location of the match is the correct offset required for aBridgeType
- // to fit, and that the string begins with aBridgeType
- if (
- key.search(pattern) == aBridgeType.length &&
- key.startsWith(aBridgeType)
- ) {
- let bridgeStr = bridgeBranch.getCharPref(key);
- retval.push(bridgeStr);
- }
- }
-
- // fisher-yates shuffle
- // shuffle so that Tor Browser users don't all try the built-in bridges in the same order
- for (let i = retval.length - 1; i > 0; --i) {
- // number n such that 0.0 <= n < 1.0
- const n = Math.random();
- // integer j such that 0 <= j <= i
- const j = Math.floor(n * (i + 1));
-
- // swap values at indices i and j
- const tmp = retval[i];
- retval[i] = retval[j];
- retval[j] = tmp;
- }
-
- return retval;
- }
-
- _readBridgeDBBridges() {
- let bridgeBranch = Services.prefs.getBranch(
- `${TorStrings.preferenceBranches.bridgeDBBridges}`
- );
- let bridgeBranchPrefs = bridgeBranch.getChildList("", {});
- // the child prefs do not come in any particular order so sort the keys
- // so the values can be compared to what we get out off torrc
- bridgeBranchPrefs.sort();
-
- // just assume all of the prefs under the parent point to valid bridge string
- let retval = bridgeBranchPrefs.map(key =>
- bridgeBranch.getCharPref(key).trim()
- );
-
- return retval;
- }
-
- _readTorrcBridges() {
- let bridgeList = TorProtocolService.readStringArraySetting(
- TorStrings.configKeys.bridgeList
- );
-
- let retval = [];
- for (const line of bridgeList) {
- let trimmedLine = line.trim();
- if (trimmedLine) {
- retval.push(trimmedLine);
- }
- }
-
- return retval;
- }
-
- // analagous to initBridgeSettings()
- readSettings() {
- // restore to defaults
- this._bridgeSource = TorBridgeSource.NONE;
- this._selectedDefaultBridgeType = null;
- this._bridgeStrings = [];
-
- // So the way tor-launcher determines the origin of the configured bridges is a bit
- // weird and depends on inferring our scenario based on some firefox prefs and the
- // relationship between the saved list of bridges in about:config vs the list saved in torrc
-
- // first off, if "extensions.torlauncher.default_bridge_type" is set to one of our
- // builtin default types (obfs4, meek-azure, snowflake, etc) then we provide the
- // bridges in "extensions.torlauncher.default_bridge.*" (filtered by our default_bridge_type)
-
- // next, we compare the list of bridges saved in torrc to the bridges stored in the
- // "extensions.torlauncher.bridgedb_bridge."" branch. If they match *exactly* then we assume
- // the bridges were retrieved from BridgeDB and use those. If the torrc list is empty then we know
- // we have no bridge settings
-
- // finally, if none of the previous conditions are not met, it is assumed the bridges stored in
- // torrc are user-provided
-
- // what we should(?) do once we excise tor-launcher entirely is explicitly store an int/enum in
- // about:config that tells us which scenario we are in so we don't have to guess
-
- let defaultBridgeType = Services.prefs.getCharPref(
- TorStrings.preferenceKeys.defaultBridgeType,
- null
- );
-
- // check if source is BUILTIN
- if (defaultBridgeType) {
- this._bridgeStrings = this._readDefaultBridges(defaultBridgeType);
- this._bridgeSource = TorBridgeSource.BUILTIN;
- this._selectedDefaultBridgeType = defaultBridgeType;
- return;
- }
-
- let torrcBridges = this._readTorrcBridges();
-
- // no stored bridges means no bridge is in use
- if (torrcBridges.length == 0) {
- this._bridgeStrings = [];
- this._bridgeSource = TorBridgeSource.NONE;
- return;
- }
-
- let bridgedbBridges = this._readBridgeDBBridges();
-
- // if these two lists are equal then we got our bridges from bridgedb
- // ie: same element in identical order
- let arraysEqual = (left, right) => {
- if (left.length != right.length) {
- return false;
- }
- const length = left.length;
- for (let i = 0; i < length; ++i) {
- if (left[i] != right[i]) {
- return false;
- }
- }
- return true;
- };
-
- // agreement between prefs and torrc means bridgedb bridges
- if (arraysEqual(torrcBridges, bridgedbBridges)) {
- this._bridgeStrings = torrcBridges;
- this._bridgeSource = TorBridgeSource.BRIDGEDB;
- return;
- }
-
- // otherwise they must be user provided
- this._bridgeStrings = torrcBridges;
- this._bridgeSource = TorBridgeSource.USERPROVIDED;
- }
-
- writeSettings() {
- let settingsObject = new Map();
-
- // init tor bridge settings to null
- settingsObject.set(TorStrings.configKeys.useBridges, null);
- settingsObject.set(TorStrings.configKeys.bridgeList, null);
-
- // clear bridge related firefox prefs
- Services.prefs.setCharPref(TorStrings.preferenceKeys.defaultBridgeType, "");
- let bridgeBranch = Services.prefs.getBranch(
- `${TorStrings.preferenceBranches.bridgeDBBridges}`
- );
- let bridgeBranchPrefs = bridgeBranch.getChildList("", {});
- for (const pref of bridgeBranchPrefs) {
- Services.prefs.clearUserPref(
- `${TorStrings.preferenceBranches.bridgeDBBridges}${pref}`
- );
- }
-
- switch (this._bridgeSource) {
- case TorBridgeSource.BUILTIN:
- // set builtin bridge type to use in prefs
- Services.prefs.setCharPref(
- TorStrings.preferenceKeys.defaultBridgeType,
- this._selectedDefaultBridgeType
- );
- break;
- case TorBridgeSource.BRIDGEDB:
- // save bridges off to prefs
- for (let i = 0; i < this.bridgeStringsArray.length; ++i) {
- Services.prefs.setCharPref(
- `${TorStrings.preferenceBranches.bridgeDBBridges}${i}`,
- this.bridgeStringsArray[i]
- );
- }
- break;
- }
-
- // write over our bridge list if bridges are enabled
- if (this._bridgeSource != TorBridgeSource.NONE) {
- settingsObject.set(TorStrings.configKeys.useBridges, true);
- settingsObject.set(
- TorStrings.configKeys.bridgeList,
- this.bridgeStringsArray
- );
- }
- TorProtocolService.writeSettings(settingsObject);
- }
-}
-
-function makeTorBridgeSettingsNone() {
- return new TorBridgeSettings();
-}
-
-function makeTorBridgeSettingsBuiltin(aBridgeType) {
- let retval = new TorBridgeSettings();
- retval._bridgeSource = TorBridgeSource.BUILTIN;
- retval._selectedDefaultBridgeType = aBridgeType;
- retval._bridgeStrings = retval._readDefaultBridges(aBridgeType);
-
- return retval;
-}
-
-function makeTorBridgeSettingsBridgeDB(aBridges) {
- let retval = new TorBridgeSettings();
- retval._bridgeSource = TorBridgeSource.BRIDGEDB;
- retval._selectedDefaultBridgeType = null;
- retval._bridgeStrings = aBridges;
-
- return retval;
-}
-
-function makeTorBridgeSettingsUserProvided(aBridges) {
- let retval = new TorBridgeSettings();
- retval._bridgeSource = TorBridgeSource.USERPROVIDED;
- retval._selectedDefaultBridgeType = null;
- retval._bridgeStrings = aBridges;
-
- return retval;
-}
diff --git a/browser/components/torpreferences/content/torFirewallSettings.jsm b/browser/components/torpreferences/content/torFirewallSettings.jsm
deleted file mode 100644
index e77f18ef2fae..000000000000
--- a/browser/components/torpreferences/content/torFirewallSettings.jsm
+++ /dev/null
@@ -1,72 +0,0 @@
-"use strict";
-
-var EXPORTED_SYMBOLS = [
- "TorFirewallSettings",
- "makeTorFirewallSettingsNone",
- "makeTorFirewallSettingsCustom",
-];
-
-const { TorProtocolService } = ChromeUtils.import(
- "resource:///modules/TorProtocolService.jsm"
-);
-const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
-const { parseAddrPortList } = ChromeUtils.import(
- "chrome://browser/content/torpreferences/parseFunctions.jsm"
-);
-
-class TorFirewallSettings {
- constructor() {
- this._allowedPorts = [];
- }
-
- get portsConfigurationString() {
- let portStrings = this._allowedPorts.map(port => `*:${port}`);
- return portStrings.join(",");
- }
-
- get commaSeparatedListString() {
- return this._allowedPorts.join(",");
- }
-
- get hasPorts() {
- return this._allowedPorts.length > 0;
- }
-
- readSettings() {
- let addressPortList = TorProtocolService.readStringSetting(
- TorStrings.configKeys.reachableAddresses
- );
-
- let allowedPorts = [];
- if (addressPortList) {
- allowedPorts = parseAddrPortList(addressPortList);
- }
- this._allowedPorts = allowedPorts;
- }
-
- writeSettings() {
- let settingsObject = new Map();
-
- // init to null so Tor daemon resets if no ports
- settingsObject.set(TorStrings.configKeys.reachableAddresses, null);
-
- if (this._allowedPorts.length > 0) {
- settingsObject.set(
- TorStrings.configKeys.reachableAddresses,
- this.portsConfigurationString
- );
- }
-
- TorProtocolService.writeSettings(settingsObject);
- }
-}
-
-function makeTorFirewallSettingsNone() {
- return new TorFirewallSettings();
-}
-
-function makeTorFirewallSettingsCustom(aPortsList) {
- let retval = new TorFirewallSettings();
- retval._allowedPorts = aPortsList;
- return retval;
-}
diff --git a/browser/components/torpreferences/content/torPane.js b/browser/components/torpreferences/content/torPane.js
index 1f169cbe1a55..6905cbe473ac 100644
--- a/browser/components/torpreferences/content/torPane.js
+++ b/browser/components/torpreferences/content/torPane.js
@@ -2,6 +2,10 @@
/* global Services */
+const { TorSettings, TorSettingsTopics, TorSettingsData, TorBridgeSource, TorBuiltinBridgeTypes, TorProxyType } = ChromeUtils.import(
+ "resource:///modules/TorSettings.jsm"
+);
+
const { TorProtocolService } = ChromeUtils.import(
"resource:///modules/TorProtocolService.jsm"
);
@@ -10,35 +14,6 @@ const { TorConnect, TorConnectTopics, TorConnectState } = ChromeUtils.import(
"resource:///modules/TorConnect.jsm"
);
-const {
- TorBridgeSource,
- TorBridgeSettings,
- makeTorBridgeSettingsNone,
- makeTorBridgeSettingsBuiltin,
- makeTorBridgeSettingsBridgeDB,
- makeTorBridgeSettingsUserProvided,
-} = ChromeUtils.import(
- "chrome://browser/content/torpreferences/torBridgeSettings.jsm"
-);
-
-const {
- TorProxyType,
- TorProxySettings,
- makeTorProxySettingsNone,
- makeTorProxySettingsSocks4,
- makeTorProxySettingsSocks5,
- makeTorProxySettingsHTTPS,
-} = ChromeUtils.import(
- "chrome://browser/content/torpreferences/torProxySettings.jsm"
-);
-const {
- TorFirewallSettings,
- makeTorFirewallSettingsNone,
- makeTorFirewallSettingsCustom,
-} = ChromeUtils.import(
- "chrome://browser/content/torpreferences/torFirewallSettings.jsm"
-);
-
const { TorLogDialog } = ChromeUtils.import(
"chrome://browser/content/torpreferences/torLogDialog.jsm"
);
@@ -53,14 +28,6 @@ ChromeUtils.defineModuleGetter(
"resource:///modules/TorStrings.jsm"
);
-const { parsePort, parseBridgeStrings, parsePortList } = ChromeUtils.import(
- "chrome://browser/content/torpreferences/parseFunctions.jsm"
-);
-
-const TorLauncherPrefs = {
- quickstart: "extensions.torlauncher.quickstart",
-}
-
/*
Tor Pane
@@ -261,10 +228,11 @@ const gTorPane = (function() {
);
this._enableQuickstartCheckbox.addEventListener("command", e => {
const checked = this._enableQuickstartCheckbox.checked;
- Services.prefs.setBoolPref(TorLauncherPrefs.quickstart, checked);
+ TorSettings.quickstart.enabled = checked;
+ TorSettings.saveToPrefs().applySettings();
});
- this._enableQuickstartCheckbox.checked = Services.prefs.getBoolPref(TorLauncherPrefs.quickstart);
- Services.prefs.addObserver(TorLauncherPrefs.quickstart, this);
+ this._enableQuickstartCheckbox.checked = TorSettings.quickstart.enabled;
+ Services.obs.addObserver(this, TorSettingsTopics.SettingChanged);
// Bridge setup
prefpane.querySelector(selectors.bridges.header).innerText =
@@ -291,7 +259,7 @@ const gTorPane = (function() {
this._bridgeSelectionRadiogroup = prefpane.querySelector(
selectors.bridges.bridgeSelectionRadiogroup
);
- this._bridgeSelectionRadiogroup.value = TorBridgeSource.BUILTIN;
+ this._bridgeSelectionRadiogroup.value = TorBridgeSource.BuiltIn;
this._bridgeSelectionRadiogroup.addEventListener("command", e => {
const value = this._bridgeSelectionRadiogroup.value;
gTorPane.onSelectBridgeOption(value).onUpdateBridgeSettings();
@@ -305,7 +273,7 @@ const gTorPane = (function() {
"label",
TorStrings.settings.selectBridge
);
- this._builtinBridgeOption.setAttribute("value", TorBridgeSource.BUILTIN);
+ this._builtinBridgeOption.setAttribute("value", TorBridgeSource.BuiltIn);
this._builtinBridgeMenulist = prefpane.querySelector(
selectors.bridges.builtinBridgeList
);
@@ -321,7 +289,7 @@ const gTorPane = (function() {
"label",
TorStrings.settings.requestBridgeFromTorProject
);
- this._requestBridgeOption.setAttribute("value", TorBridgeSource.BRIDGEDB);
+ this._requestBridgeOption.setAttribute("value", TorBridgeSource.BridgeDB);
this._requestBridgeButton = prefpane.querySelector(
selectors.bridges.requestBridgeButton
);
@@ -346,7 +314,7 @@ const gTorPane = (function() {
);
this._provideBridgeOption.setAttribute(
"value",
- TorBridgeSource.USERPROVIDED
+ TorBridgeSource.UserProvided
);
prefpane.querySelector(
selectors.bridges.provideBridgeDescription
@@ -395,11 +363,11 @@ const gTorPane = (function() {
let mockProxies = [
{
- value: TorProxyType.SOCKS4,
+ value: TorProxyType.Socks4,
label: TorStrings.settings.proxyTypeSOCKS4,
},
{
- value: TorProxyType.SOCKS5,
+ value: TorProxyType.Socks5,
label: TorStrings.settings.proxyTypeSOCKS5,
},
{ value: TorProxyType.HTTPS, label: TorStrings.settings.proxyTypeHTTP },
@@ -550,12 +518,8 @@ const gTorPane = (function() {
true
);
- // load bridge settings
- let torBridgeSettings = new TorBridgeSettings();
- torBridgeSettings.readSettings();
-
- // populate the bridge list
- for (let currentBridge of TorBridgeSettings.defaultBridgeTypes) {
+ // init bridge UI
+ for (let currentBridge of TorBuiltinBridgeTypes) {
let menuEntry = document.createXULElement("menuitem");
menuEntry.setAttribute("value", currentBridge);
menuEntry.setAttribute("label", currentBridge);
@@ -564,53 +528,41 @@ const gTorPane = (function() {
.appendChild(menuEntry);
}
- this.onSelectBridgeOption(torBridgeSettings.bridgeSource);
- this.onToggleBridge(
- torBridgeSettings.bridgeSource != TorBridgeSource.NONE
- );
- switch (torBridgeSettings.bridgeSource) {
- case TorBridgeSource.NONE:
- break;
- case TorBridgeSource.BUILTIN:
- this._builtinBridgeMenulist.value =
- torBridgeSettings.selectedDefaultBridgeType;
- break;
- case TorBridgeSource.BRIDGEDB:
- this._requestBridgeTextarea.value = torBridgeSettings.bridgeStrings;
- break;
- case TorBridgeSource.USERPROVIDED:
- this._provideBridgeTextarea.value = torBridgeSettings.bridgeStrings;
- break;
+ if (TorSettings.bridges.enabled) {
+ this.onSelectBridgeOption(TorSettings.bridges.source);
+ this.onToggleBridge(
+ TorSettings.bridges.source != TorBridgeSource.Invalid
+ );
+ switch (TorSettings.bridges.source) {
+ case TorBridgeSource.Invalid:
+ break;
+ case TorBridgeSource.BuiltIn:
+ this._builtinBridgeMenulist.value = TorSettings.bridges.builtin_type;
+ break;
+ case TorBridgeSource.BridgeDB:
+ this._requestBridgeTextarea.value = TorSettings.bridges.bridge_strings.join("\n");
+ break;
+ case TorBridgeSource.UserProvided:
+ this._provideBridgeTextarea.value = TorSettings.bridges.bridge_strings.join("\n");
+ break;
+ }
}
- this._bridgeSettings = torBridgeSettings;
-
- // load proxy settings
- let torProxySettings = new TorProxySettings();
- torProxySettings.readSettings();
-
- if (torProxySettings.type != TorProxyType.NONE) {
+ // init proxy UI
+ if (TorSettings.proxy.enabled) {
this.onToggleProxy(true);
- this.onSelectProxyType(torProxySettings.type);
- this._proxyAddressTextbox.value = torProxySettings.address;
- this._proxyPortTextbox.value = torProxySettings.port;
- this._proxyUsernameTextbox.value = torProxySettings.username;
- this._proxyPasswordTextbox.value = torProxySettings.password;
+ this.onSelectProxyType(TorSettings.proxy.type);
+ this._proxyAddressTextbox.value = TorSettings.proxy.address;
+ this._proxyPortTextbox.value = TorSettings.proxy.port;
+ this._proxyUsernameTextbox.value = TorSettings.proxy.username;
+ this._proxyPasswordTextbox.value = TorSettings.proxy.password;
}
- this._proxySettings = torProxySettings;
-
- // load firewall settings
- let torFirewallSettings = new TorFirewallSettings();
- torFirewallSettings.readSettings();
-
- if (torFirewallSettings.hasPorts) {
+ // init firewall
+ if (TorSettings.firewall.enabled) {
this.onToggleFirewall(true);
- this._allowedPortsTextbox.value =
- torFirewallSettings.commaSeparatedListString;
+ this._allowedPortsTextbox.value = TorSettings.firewall.allowed_ports.join(", ");
}
-
- this._firewallSettings = torFirewallSettings;
},
init() {
@@ -683,13 +635,17 @@ const gTorPane = (function() {
if (enabled) {
this.onSelectBridgeOption(this._bridgeSelectionRadiogroup.value);
} else {
- this.onSelectBridgeOption(TorBridgeSource.NONE);
+ this.onSelectBridgeOption(TorBridgeSource.Invalid);
}
return this;
},
// callback when a bridge option is selected
onSelectBridgeOption(source) {
+ if (typeof source === "string") {
+ source = parseInt(source);
+ }
+
// disable all of the bridge elements under radio buttons
this._setElementsDisabled(
[
@@ -701,23 +657,23 @@ const gTorPane = (function() {
true
);
- if (source != TorBridgeSource.NONE) {
+ if (source != TorBridgeSource.Invalid) {
this._bridgeSelectionRadiogroup.value = source;
}
switch (source) {
- case TorBridgeSource.BUILTIN: {
+ case TorBridgeSource.BuiltIn: {
this._setElementsDisabled([this._builtinBridgeMenulist], false);
break;
}
- case TorBridgeSource.BRIDGEDB: {
+ case TorBridgeSource.BridgeDB: {
this._setElementsDisabled(
[this._requestBridgeButton, this._requestBridgeTextarea],
false
);
break;
}
- case TorBridgeSource.USERPROVIDED: {
+ case TorBridgeSource.UserProvided: {
this._setElementsDisabled([this._provideBridgeTextarea], false);
break;
}
@@ -730,14 +686,17 @@ const gTorPane = (function() {
let requestBridgeDialog = new RequestBridgeDialog();
requestBridgeDialog.openDialog(
gSubDialog,
- this._proxySettings.proxyURI,
+ TorSettings.proxy.uri,
aBridges => {
if (aBridges.length > 0) {
- let bridgeSettings = makeTorBridgeSettingsBridgeDB(aBridges);
- bridgeSettings.writeSettings();
- this._bridgeSettings = bridgeSettings;
-
- this._requestBridgeTextarea.value = bridgeSettings.bridgeStrings;
+ let bridgeStrings = aBridges.join("\n");
+ TorSettings.bridges.enabled = true;
+ TorSettings.bridges.source = TorBridgeSource.BridgeDB;
+ TorSettings.bridges.bridge_strings = bridgeStrings;
+ TorSettings.saveToPrefs();
+ TorSettings.applySettings().then((result) => {
+ this._requestBridgeTextarea.value = bridgeStrings;
+ });
}
}
);
@@ -746,53 +705,56 @@ const gTorPane = (function() {
// pushes bridge settings from UI to tor
onUpdateBridgeSettings() {
- let bridgeSettings = null;
-
let source = this._useBridgeCheckbox.checked
- ? this._bridgeSelectionRadiogroup.value
- : TorBridgeSource.NONE;
+ ? parseInt(this._bridgeSelectionRadiogroup.value)
+ : TorBridgeSource.Invalid;
+
switch (source) {
- case TorBridgeSource.NONE: {
- bridgeSettings = makeTorBridgeSettingsNone();
- break;
+ case TorBridgeSource.Invalid: {
+ TorSettings.bridges.enabled = false;
}
- case TorBridgeSource.BUILTIN: {
+ break;
+ case TorBridgeSource.BuiltIn: {
// if there is a built-in bridge already selected, use that
let bridgeType = this._builtinBridgeMenulist.value;
+ console.log(`bridge type: ${bridgeType}`);
if (bridgeType) {
- bridgeSettings = makeTorBridgeSettingsBuiltin(bridgeType);
+ TorSettings.bridges.enabled = true;
+ TorSettings.bridges.source = TorBridgeSource.BuiltIn;
+ TorSettings.bridges.builtin_type = bridgeType;
} else {
- bridgeSettings = makeTorBridgeSettingsNone();
+ TorSettings.bridges.enabled = false;
}
break;
}
- case TorBridgeSource.BRIDGEDB: {
+ case TorBridgeSource.BridgeDB: {
// if there are bridgedb bridges saved in the text area, use them
let bridgeStrings = this._requestBridgeTextarea.value;
if (bridgeStrings) {
- let bridgeStringList = parseBridgeStrings(bridgeStrings);
- bridgeSettings = makeTorBridgeSettingsBridgeDB(bridgeStringList);
+ TorSettings.bridges.enabled = true;
+ TorSettings.bridges.source = TorBridgeSource.BridgeDB;
+ TorSettings.bridges.bridge_strings = bridgeStrings;
} else {
- bridgeSettings = makeTorBridgeSettingsNone();
+ TorSettings.bridges.enabled = false;
}
break;
}
- case TorBridgeSource.USERPROVIDED: {
+ case TorBridgeSource.UserProvided: {
// if bridges already exist in the text area, use them
let bridgeStrings = this._provideBridgeTextarea.value;
if (bridgeStrings) {
- let bridgeStringList = parseBridgeStrings(bridgeStrings);
- bridgeSettings = makeTorBridgeSettingsUserProvided(
- bridgeStringList
- );
+ TorSettings.bridges.enabled = true;
+ TorSettings.bridges.source = TorBridgeSource.UserProvided;
+ TorSettings.bridges.bridge_strings = bridgeStrings;
} else {
- bridgeSettings = makeTorBridgeSettingsNone();
+ TorSettings.bridges.enabled = false;
}
break;
}
}
- bridgeSettings.writeSettings();
- this._bridgeSettings = bridgeSettings;
+ TorSettings.saveToPrefs();
+ TorSettings.applySettings();
+
return this;
},
@@ -822,12 +784,13 @@ const gTorPane = (function() {
// callback when proxy type is changed
onSelectProxyType(value) {
- if (value == "") {
- value = TorProxyType.NONE;
+ if (typeof value === "string") {
+ value = parseInt(value);
}
+
this._proxyTypeMenulist.value = value;
switch (value) {
- case TorProxyType.NONE: {
+ case TorProxyType.Invalid: {
this._setElementsDisabled(
[
this._proxyAddressLabel,
@@ -848,7 +811,7 @@ const gTorPane = (function() {
this._proxyPasswordTextbox.value = "";
break;
}
- case TorProxyType.SOCKS4: {
+ case TorProxyType.Socks4: {
this._setElementsDisabled(
[
this._proxyAddressLabel,
@@ -872,7 +835,7 @@ const gTorPane = (function() {
this._proxyPasswordTextbox.value = "";
break;
}
- case TorProxyType.SOCKS5:
+ case TorProxyType.Socks5:
case TorProxyType.HTTPS: {
this._setElementsDisabled(
[
@@ -895,46 +858,45 @@ const gTorPane = (function() {
// pushes proxy settings from UI to tor
onUpdateProxySettings() {
- const proxyType = this._useProxyCheckbox.checked
- ? this._proxyTypeMenulist.value
- : TorProxyType.NONE;
- const addressString = this._proxyAddressTextbox.value;
- const portString = this._proxyPortTextbox.value;
- const usernameString = this._proxyUsernameTextbox.value;
- const passwordString = this._proxyPasswordTextbox.value;
-
- let proxySettings = null;
-
- switch (proxyType) {
- case TorProxyType.NONE:
- proxySettings = makeTorProxySettingsNone();
+ const type = this._useProxyCheckbox.checked
+ ? parseInt(this._proxyTypeMenulist.value)
+ : TorProxyType.Invalid;
+ const address = this._proxyAddressTextbox.value;
+ const port = this._proxyPortTextbox.value;
+ const username = this._proxyUsernameTextbox.value;
+ const password = this._proxyPasswordTextbox.value;
+
+ switch (type) {
+ case TorProxyType.Invalid:
+ TorSettings.proxy.enabled = false;
break;
- case TorProxyType.SOCKS4:
- proxySettings = makeTorProxySettingsSocks4(
- addressString,
- parsePort(portString)
- );
+ case TorProxyType.Socks4:
+ TorSettings.proxy.enabled = true;
+ TorSettings.proxy.type = type;
+ TorSettings.proxy.address = address;
+ TorSettings.proxy.port = port;
+
break;
- case TorProxyType.SOCKS5:
- proxySettings = makeTorProxySettingsSocks5(
- addressString,
- parsePort(portString),
- usernameString,
- passwordString
- );
+ case TorProxyType.Socks5:
+ TorSettings.proxy.enabled = true;
+ TorSettings.proxy.type = type;
+ TorSettings.proxy.address = address;
+ TorSettings.proxy.port = port;
+ TorSettings.proxy.username = username;
+ TorSettings.proxy.password = password;
break;
case TorProxyType.HTTPS:
- proxySettings = makeTorProxySettingsHTTPS(
- addressString,
- parsePort(portString),
- usernameString,
- passwordString
- );
+ TorSettings.proxy.enabled = true;
+ TorSettings.proxy.type = type;
+ TorSettings.proxy.address = address;
+ TorSettings.proxy.port = port;
+ TorSettings.proxy.username = username;
+ TorSettings.proxy.password = password;
break;
}
+ TorSettings.saveToPrefs();
+ TorSettings.applySettings();
- proxySettings.writeSettings();
- this._proxySettings = proxySettings;
return this;
},
@@ -953,21 +915,20 @@ const gTorPane = (function() {
// pushes firewall settings from UI to tor
onUpdateFirewallSettings() {
+
let portListString = this._useFirewallCheckbox.checked
? this._allowedPortsTextbox.value
: "";
- let firewallSettings = null;
if (portListString) {
- firewallSettings = makeTorFirewallSettingsCustom(
- parsePortList(portListString)
- );
+ TorSettings.firewall.enabled = true;
+ TorSettings.firewall.allowed_ports = portListString;
} else {
- firewallSettings = makeTorFirewallSettingsNone();
+ TorSettings.firewall.enabled = false;
}
+ TorSettings.saveToPrefs();
+ TorSettings.applySettings();
- firewallSettings.writeSettings();
- this._firewallSettings = firewallSettings;
return this;
},
diff --git a/browser/components/torpreferences/content/torProxySettings.jsm b/browser/components/torpreferences/content/torProxySettings.jsm
deleted file mode 100644
index 98bb5e8d5cbf..000000000000
--- a/browser/components/torpreferences/content/torProxySettings.jsm
+++ /dev/null
@@ -1,245 +0,0 @@
-"use strict";
-
-var EXPORTED_SYMBOLS = [
- "TorProxyType",
- "TorProxySettings",
- "makeTorProxySettingsNone",
- "makeTorProxySettingsSocks4",
- "makeTorProxySettingsSocks5",
- "makeTorProxySettingsHTTPS",
-];
-
-const { TorProtocolService } = ChromeUtils.import(
- "resource:///modules/TorProtocolService.jsm"
-);
-const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
-const { parseAddrPort, parseUsernamePassword } = ChromeUtils.import(
- "chrome://browser/content/torpreferences/parseFunctions.jsm"
-);
-
-const TorProxyType = {
- NONE: "NONE",
- SOCKS4: "SOCKS4",
- SOCKS5: "SOCKS5",
- HTTPS: "HTTPS",
-};
-
-class TorProxySettings {
- constructor() {
- this._proxyType = TorProxyType.NONE;
- this._proxyAddress = undefined;
- this._proxyPort = undefined;
- this._proxyUsername = undefined;
- this._proxyPassword = undefined;
- }
-
- get type() {
- return this._proxyType;
- }
- get address() {
- return this._proxyAddress;
- }
- get port() {
- return this._proxyPort;
- }
- get username() {
- return this._proxyUsername;
- }
- get password() {
- return this._proxyPassword;
- }
- get proxyURI() {
- switch (this._proxyType) {
- case TorProxyType.SOCKS4:
- return `socks4a://${this._proxyAddress}:${this._proxyPort}`;
- case TorProxyType.SOCKS5:
- if (this._proxyUsername) {
- return `socks5://${this._proxyUsername}:${this._proxyPassword}@${
- this._proxyAddress
- }:${this._proxyPort}`;
- }
- return `socks5://${this._proxyAddress}:${this._proxyPort}`;
- case TorProxyType.HTTPS:
- if (this._proxyUsername) {
- return `http://${this._proxyUsername}:${this._proxyPassword}@${
- this._proxyAddress
- }:${this._proxyPort}`;
- }
- return `http://${this._proxyAddress}:${this._proxyPort}`;
- }
- return undefined;
- }
-
- // attempts to read proxy settings from Tor daemon
- readSettings() {
- // SOCKS4
- {
- let addressPort = TorProtocolService.readStringSetting(
- TorStrings.configKeys.socks4Proxy
- );
- if (addressPort) {
- // address+port
- let [proxyAddress, proxyPort] = parseAddrPort(addressPort);
-
- this._proxyType = TorProxyType.SOCKS4;
- this._proxyAddress = proxyAddress;
- this._proxyPort = proxyPort;
- this._proxyUsername = "";
- this._proxyPassword = "";
-
- return;
- }
- }
-
- // SOCKS5
- {
- let addressPort = TorProtocolService.readStringSetting(
- TorStrings.configKeys.socks5Proxy
- );
-
- if (addressPort) {
- // address+port
- let [proxyAddress, proxyPort] = parseAddrPort(addressPort);
- // username
- let proxyUsername = TorProtocolService.readStringSetting(
- TorStrings.configKeys.socks5ProxyUsername
- );
- // password
- let proxyPassword = TorProtocolService.readStringSetting(
- TorStrings.configKeys.socks5ProxyPassword
- );
-
- this._proxyType = TorProxyType.SOCKS5;
- this._proxyAddress = proxyAddress;
- this._proxyPort = proxyPort;
- this._proxyUsername = proxyUsername;
- this._proxyPassword = proxyPassword;
-
- return;
- }
- }
-
- // HTTP
- {
- let addressPort = TorProtocolService.readStringSetting(
- TorStrings.configKeys.httpsProxy
- );
-
- if (addressPort) {
- // address+port
- let [proxyAddress, proxyPort] = parseAddrPort(addressPort);
-
- // username:password
- let proxyAuthenticator = TorProtocolService.readStringSetting(
- TorStrings.configKeys.httpsProxyAuthenticator
- );
-
- let [proxyUsername, proxyPassword] = ["", ""];
- if (proxyAuthenticator) {
- [proxyUsername, proxyPassword] = parseUsernamePassword(
- proxyAuthenticator
- );
- }
-
- this._proxyType = TorProxyType.HTTPS;
- this._proxyAddress = proxyAddress;
- this._proxyPort = proxyPort;
- this._proxyUsername = proxyUsername;
- this._proxyPassword = proxyPassword;
- }
- }
- // no proxy settings
- } /* TorProxySettings::ReadFromTor() */
-
- // attempts to write proxy settings to Tor daemon
- // throws on error
- writeSettings() {
- let settingsObject = new Map();
-
- // init proxy related settings to null so Tor daemon resets them
- settingsObject.set(TorStrings.configKeys.socks4Proxy, null);
- settingsObject.set(TorStrings.configKeys.socks5Proxy, null);
- settingsObject.set(TorStrings.configKeys.socks5ProxyUsername, null);
- settingsObject.set(TorStrings.configKeys.socks5ProxyPassword, null);
- settingsObject.set(TorStrings.configKeys.httpsProxy, null);
- settingsObject.set(TorStrings.configKeys.httpsProxyAuthenticator, null);
-
- switch (this._proxyType) {
- case TorProxyType.SOCKS4:
- settingsObject.set(
- TorStrings.configKeys.socks4Proxy,
- `${this._proxyAddress}:${this._proxyPort}`
- );
- break;
- case TorProxyType.SOCKS5:
- settingsObject.set(
- TorStrings.configKeys.socks5Proxy,
- `${this._proxyAddress}:${this._proxyPort}`
- );
- settingsObject.set(
- TorStrings.configKeys.socks5ProxyUsername,
- this._proxyUsername
- );
- settingsObject.set(
- TorStrings.configKeys.socks5ProxyPassword,
- this._proxyPassword
- );
- break;
- case TorProxyType.HTTPS:
- settingsObject.set(
- TorStrings.configKeys.httpsProxy,
- `${this._proxyAddress}:${this._proxyPort}`
- );
- settingsObject.set(
- TorStrings.configKeys.httpsProxyAuthenticator,
- `${this._proxyUsername}:${this._proxyPassword}`
- );
- break;
- }
-
- TorProtocolService.writeSettings(settingsObject);
- } /* TorProxySettings::WriteToTor() */
-}
-
-// factory methods for our various supported proxies
-function makeTorProxySettingsNone() {
- return new TorProxySettings();
-}
-
-function makeTorProxySettingsSocks4(aProxyAddress, aProxyPort) {
- let retval = new TorProxySettings();
- retval._proxyType = TorProxyType.SOCKS4;
- retval._proxyAddress = aProxyAddress;
- retval._proxyPort = aProxyPort;
- return retval;
-}
-
-function makeTorProxySettingsSocks5(
- aProxyAddress,
- aProxyPort,
- aProxyUsername,
- aProxyPassword
-) {
- let retval = new TorProxySettings();
- retval._proxyType = TorProxyType.SOCKS5;
- retval._proxyAddress = aProxyAddress;
- retval._proxyPort = aProxyPort;
- retval._proxyUsername = aProxyUsername;
- retval._proxyPassword = aProxyPassword;
- return retval;
-}
-
-function makeTorProxySettingsHTTPS(
- aProxyAddress,
- aProxyPort,
- aProxyUsername,
- aProxyPassword
-) {
- let retval = new TorProxySettings();
- retval._proxyType = TorProxyType.HTTPS;
- retval._proxyAddress = aProxyAddress;
- retval._proxyPort = aProxyPort;
- retval._proxyUsername = aProxyUsername;
- retval._proxyPassword = aProxyPassword;
- return retval;
-}
diff --git a/browser/components/torpreferences/jar.mn b/browser/components/torpreferences/jar.mn
index 857bc9ee3eac..552c92b2feff 100644
--- a/browser/components/torpreferences/jar.mn
+++ b/browser/components/torpreferences/jar.mn
@@ -1,14 +1,10 @@
browser.jar:
- content/browser/torpreferences/parseFunctions.jsm (content/parseFunctions.jsm)
- content/browser/torpreferences/requestBridgeDialog.xhtml (content/requestBridgeDialog.xhtml)
+ content/browser/torpreferences/requestBridgeDialog.xhtml (content/requestBridgeDialog.xhtml)
content/browser/torpreferences/requestBridgeDialog.jsm (content/requestBridgeDialog.jsm)
- content/browser/torpreferences/torBridgeSettings.jsm (content/torBridgeSettings.jsm)
- content/browser/torpreferences/torCategory.inc.xhtml (content/torCategory.inc.xhtml)
- content/browser/torpreferences/torFirewallSettings.jsm (content/torFirewallSettings.jsm)
+ content/browser/torpreferences/torCategory.inc.xhtml (content/torCategory.inc.xhtml)
content/browser/torpreferences/torLogDialog.jsm (content/torLogDialog.jsm)
- content/browser/torpreferences/torLogDialog.xhtml (content/torLogDialog.xhtml)
+ content/browser/torpreferences/torLogDialog.xhtml (content/torLogDialog.xhtml)
content/browser/torpreferences/torPane.js (content/torPane.js)
- content/browser/torpreferences/torPane.xhtml (content/torPane.xhtml)
+ content/browser/torpreferences/torPane.xhtml (content/torPane.xhtml)
content/browser/torpreferences/torPreferences.css (content/torPreferences.css)
content/browser/torpreferences/torPreferencesIcon.svg (content/torPreferencesIcon.svg)
- content/browser/torpreferences/torProxySettings.jsm (content/torProxySettings.jsm)
diff --git a/browser/modules/TorConnect.jsm b/browser/modules/TorConnect.jsm
index 19a3f595d490..e7b8b364db86 100644
--- a/browser/modules/TorConnect.jsm
+++ b/browser/modules/TorConnect.jsm
@@ -18,6 +18,10 @@ const { TorLauncherUtil } = ChromeUtils.import(
"resource://torlauncher/modules/tl-util.jsm"
);
+const { TorSettings, TorSettingsTopics } = ChromeUtils.import(
+ "resource:///modules/TorSettings.jsm"
+);
+
/* Browser observer topis */
const BrowserTopics = Object.freeze({
ProfileAfterChange: "profile-after-change",
@@ -25,7 +29,6 @@ const BrowserTopics = Object.freeze({
/* tor-launcher observer topics */
const TorTopics = Object.freeze({
- ProcessIsReady: "TorProcessIsReady",
BootstrapStatus: "TorBootstrapStatus",
BootstrapError: "TorBootstrapError",
ProcessExited: "TorProcessExited",
@@ -34,7 +37,6 @@ const TorTopics = Object.freeze({
/* Relevant prefs used by tor-launcher */
const TorLauncherPrefs = Object.freeze({
- quickstart: "extensions.torlauncher.quickstart",
prompt_at_startup: "extensions.torlauncher.prompt_at_startup",
});
@@ -250,38 +252,29 @@ const TorConnect = (() => {
// Disabled
this.legacyOrSystemTor();
} else {
- // register the Tor topics we always care about
- for (const topicKey in TorTopics) {
- const topic = TorTopics[topicKey];
+ let observeTopic = (topic) => {
Services.obs.addObserver(this, topic);
console.log(`TorConnect: observing topic '${topic}'`);
- }
+ };
- if (TorProtocolService.torProcessStatus == TorProcessStatus.Running) {
- if (this.shouldQuickStart) {
- // Quickstart
- this.beginBootstrap();
- } else {
- // Configuring
- this.beginConfigure();
- }
+ // register the Tor topics we always care about
+ for (const topicKey in TorTopics) {
+ const topic = TorTopics[topicKey];
+ observeTopic(topic);
}
+ observeTopic(TorSettingsTopics.Ready);
}
-
Services.obs.removeObserver(this, topic);
break;
}
- /* Transition out of Initial if Tor daemon wasn't running yet in BrowserTopics.ProfileAfterChange */
- case TorTopics.ProcessIsReady: {
- if (this.state === TorConnectState.Initial)
- {
- if (this.shouldQuickStart) {
- // Quickstart
- this.beginBootstrap();
- } else {
- // Configuring
- this.beginConfigure();
- }
+ /* We need to wait until TorSettings have been loaded and applied before we can Quickstart */
+ case TorSettingsTopics.Ready: {
+ if (this.shouldQuickStart) {
+ // Quickstart
+ this.beginBootstrap();
+ } else {
+ // Configuring
+ this.beginConfigure();
}
break;
}
@@ -342,7 +335,7 @@ const TorConnect = (() => {
get shouldQuickStart() {
// quickstart must be enabled
- return Services.prefs.getBoolPref(TorLauncherPrefs.quickstart, false) &&
+ return TorSettings.quickstart.enabled &&
// and the previous bootstrap attempt must have succeeded
!Services.prefs.getBoolPref(TorLauncherPrefs.prompt_at_startup, true);
},
diff --git a/browser/modules/TorSettings.jsm b/browser/modules/TorSettings.jsm
new file mode 100644
index 000000000000..6d2a6c4a07cf
--- /dev/null
+++ b/browser/modules/TorSettings.jsm
@@ -0,0 +1,814 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["TorSettings", "TorSettingsTopics", "TorSettingsData", "TorBridgeSource", "TorBuiltinBridgeTypes", "TorProxyType"];
+
+const { Services } = ChromeUtils.import(
+ "resource://gre/modules/Services.jsm"
+);
+
+const { TorProtocolService, TorProcessStatus } = ChromeUtils.import(
+ "resource:///modules/TorProtocolService.jsm"
+);
+
+/* Browser observer topics */
+const BrowserTopics = Object.freeze({
+ ProfileAfterChange: "profile-after-change",
+});
+
+/* tor-launcher observer topics */
+const TorTopics = Object.freeze({
+ ProcessIsReady: "TorProcessIsReady",
+});
+
+/* TorSettings observer topics */
+const TorSettingsTopics = Object.freeze({
+ Ready: "torsettings:ready",
+ SettingChanged: "torsettings:setting-changed",
+});
+
+/* TorSettings observer data (for SettingChanged topic) */
+const TorSettingsData = Object.freeze({
+ QuickStartEnabled : "torsettings:quickstart_enabled",
+});
+
+/* Prefs used to store settings in TorBrowser prefs */
+const TorSettingsPrefs = Object.freeze({
+ /* bool: are we pulling tor settings from the preferences */
+ enabled: 'torbrowser.settings.enabled',
+ quickstart : {
+ /* bool: does tor connect automatically on launch */
+ enabled: 'torbrowser.settings.quickstart.enabled',
+ },
+ bridges : {
+ /* bool: does tor use bridges */
+ enabled : 'torbrowser.settings.bridges.enabled',
+ /* int: -1=invalid|0=builtin|1=bridge_db|2=user_provided */
+ source : 'torbrowser.settings.bridges.source',
+ /* string: obfs4|meek_azure|snowflake|etc */
+ builtin_type : 'torbrowser.settings.bridges.builtin_type',
+ /* preference branch: each child branch should be a bridge string */
+ bridge_strings : 'torbrowser.settings.bridges.bridge_strings',
+ },
+ proxy : {
+ /* bool: does tor use a proxy */
+ enabled : 'torbrowser.settings.proxy.enabled',
+ /* -1=invalid|0=socks4,1=socks5,2=https */
+ type: 'torbrowser.settings.proxy.type',
+ /* string: proxy server address */
+ address: 'torbrowser.settings.proxy.address',
+ /* int: [1,65535], proxy port */
+ port: 'torbrowser.settings.proxy.port',
+ /* string: username */
+ username: 'torbrowser.settings.proxy.username',
+ /* string: password */
+ password: 'torbrowser.settings.proxy.password',
+ },
+ firewall : {
+ /* bool: does tor have a port allow list */
+ enabled: 'torbrowser.settings.firewall.enabled',
+ /* string: comma-delimitted list of port numbers */
+ allowed_ports: 'torbrowser.settings.firewall.allowed_ports',
+ },
+});
+
+/* Legacy tor-launcher prefs and pref branches*/
+const TorLauncherPrefs = Object.freeze({
+ quickstart: "extensions.torlauncher.quickstart",
+ default_bridge_type: "extensions.torlauncher.default_bridge_type",
+ default_bridge: "extensions.torlauncher.default_bridge.",
+ default_bridge_recommended_type: "extensions.torlauncher.default_bridge_recommended_type",
+ bridgedb_bridge: "extensions.torlauncher.bridgedb_bridge.",
+});
+
+/* Config Keys used to configure tor daemon */
+const TorConfigKeys = Object.freeze({
+ useBridges: "UseBridges",
+ bridgeList: "Bridge",
+ socks4Proxy: "Socks4Proxy",
+ socks5Proxy: "Socks5Proxy",
+ socks5ProxyUsername: "Socks5ProxyUsername",
+ socks5ProxyPassword: "Socks5ProxyPassword",
+ httpsProxy: "HTTPSProxy",
+ httpsProxyAuthenticator: "HTTPSProxyAuthenticator",
+ reachableAddresses: "ReachableAddresses",
+ clientTransportPlugin: "ClientTransportPlugin",
+});
+
+const TorBridgeSource = Object.freeze({
+ Invalid: -1,
+ BuiltIn: 0,
+ BridgeDB: 1,
+ UserProvided: 2,
+});
+
+const TorProxyType = Object.freeze({
+ Invalid: -1,
+ Socks4: 0,
+ Socks5: 1,
+ HTTPS: 2,
+});
+
+
+const TorBuiltinBridgeTypes = Object.freeze(
+ (() => {
+ let bridgeListBranch = Services.prefs.getBranch(TorLauncherPrefs.default_bridge);
+ let bridgePrefs = bridgeListBranch.getChildList("");
+
+ // an unordered set for shoving bridge types into
+ let bridgeTypes = new Set();
+ // look for keys ending in ".N" and treat string before that as the bridge type
+ const pattern = /\.[0-9]+$/;
+ for (const key of bridgePrefs) {
+ const offset = key.search(pattern);
+ if (offset != -1) {
+ const bt = key.substring(0, offset);
+ bridgeTypes.add(bt);
+ }
+ }
+
+ // recommended bridge type goes first in the list
+ let recommendedBridgeType = Services.prefs.getCharPref(TorLauncherPrefs.default_bridge_recommended_type, null);
+
+ let retval = [];
+ if (recommendedBridgeType && bridgeTypes.has(recommendedBridgeType)) {
+ retval.push(recommendedBridgeType);
+ }
+
+ for (const bridgeType of bridgeTypes.values()) {
+ if (bridgeType != recommendedBridgeType) {
+ retval.push(bridgeType);
+ }
+ }
+ return retval;
+ })()
+);
+
+/* Parsing Methods */
+
+// expects a string representation of an integer from 1 to 65535
+let parsePort = function(aPort) {
+ // ensure port string is a valid positive integer
+ const validIntRegex = /^[0-9]+$/;
+ if (!validIntRegex.test(aPort)) {
+ return 0;
+ }
+
+ // ensure port value is on valid range
+ let port = Number.parseInt(aPort);
+ if (port < 1 || port > 65535) {
+ return 0;
+ }
+
+ return port;
+};
+// expects a string in the format: "ADDRESS:PORT"
+let parseAddrPort = function(aAddrColonPort) {
+ let tokens = aAddrColonPort.split(":");
+ if (tokens.length != 2) {
+ return ["", 0];
+ }
+ let address = tokens[0];
+ let port = parsePort(tokens[1]);
+ return [address, port];
+};
+
+// expects a string in the format: "USERNAME:PASSWORD"
+// split on the first colon and any subsequent go into password
+let parseUsernamePassword = function(aUsernameColonPassword) {
+ let colonIndex = aUsernameColonPassword.indexOf(":");
+ if (colonIndex < 0) {
+ return ["", ""];
+ }
+
+ let username = aUsernameColonPassword.substring(0, colonIndex);
+ let password = aUsernameColonPassword.substring(colonIndex + 1);
+
+ return [username, password];
+};
+
+// expects a string in the format: ADDRESS:PORT,ADDRESS:PORT,...
+// returns array of ports (as ints)
+let parseAddrPortList = function(aAddrPortList) {
+ let addrPorts = aAddrPortList.split(",");
+ // parse ADDRESS:PORT string and only keep the port (second element in returned array)
+ let retval = addrPorts.map(addrPort => parseAddrPort(addrPort)[1]);
+ return retval;
+};
+
+// expects a '/n' or '/r/n' delimited bridge string, which we split and trim
+// each bridge string can also optionally have 'bridge' at the beginning ie:
+// bridge $(type) $(address):$(port) $(certificate)
+// we strip out the 'bridge' prefix here
+let parseBridgeStrings = function(aBridgeStrings) {
+
+ // replace carriage returns ('\r') with new lines ('\n')
+ aBridgeStrings = aBridgeStrings.replace(/\r/g, "\n");
+ // then replace contiguous new lines ('\n') with a single one
+ aBridgeStrings = aBridgeStrings.replace(/[\n]+/g, "\n");
+
+ // split on the newline and for each bridge string: trim, remove starting 'bridge' string
+ // finally discard entries that are empty strings; empty strings could occur if we receive
+ // a new line containing only whitespace
+ let splitStrings = aBridgeStrings.split("\n");
+ return splitStrings.map(val => val.trim().replace(/^bridge\s+/i, ""))
+ .filter(bridgeString => bridgeString != "");
+};
+
+// expecting a ',' delimited list of ints with possible white space between
+// returns an array of ints
+let parsePortList = function(aPortListString) {
+ let splitStrings = aPortListString.split(",");
+ // parse and remove duplicates
+ let portSet = new Set(splitStrings.map(val => parsePort(val.trim())));
+ // parsePort returns 0 for failed parses, so remove 0 from list
+ portSet.delete(0);
+ return Array.from(portSet);
+};
+
+let getBuiltinBridgeStrings = function(builtinType) {
+ let bridgeBranch = Services.prefs.getBranch(TorLauncherPrefs.default_bridge);
+ let bridgeBranchPrefs = bridgeBranch.getChildList("");
+ let retval = [];
+
+ // regex matches against strings ending in ".N" where N is a positive integer
+ let pattern = /\.[0-9]+$/;
+ for (const key of bridgeBranchPrefs) {
+ // verify the location of the match is the correct offset required for aBridgeType
+ // to fit, and that the string begins with aBridgeType
+ if (key.search(pattern) == builtinType.length &&
+ key.startsWith(builtinType)) {
+ let bridgeStr = bridgeBranch.getCharPref(key);
+ retval.push(bridgeStr);
+ }
+ }
+
+ // shuffle so that Tor Browser users don't all try the built-in bridges in the same order
+ arrayShuffle(retval);
+
+ return retval;
+};
+
+/* Array methods */
+
+let arrayShuffle = function(array) {
+ // fisher-yates shuffle
+ for (let i = array.length - 1; i > 0; --i) {
+ // number n such that 0.0 <= n < 1.0
+ const n = Math.random();
+ // integer j such that 0 <= j <= i
+ const j = Math.floor(n * (i + 1));
+
+ // swap values at indices i and j
+ const tmp = array[i];
+ array[i] = array[j];
+ array[j] = tmp;
+ }
+}
+
+let arrayCopy = function(array) {
+ return [].concat(array);
+}
+
+/* TorSettings module */
+
+const TorSettings = (() => {
+ let self = {
+ _settings: null,
+
+ // tor daemon related settings
+ defaultSettings: function() {
+ let settings = {
+ quickstart: {
+ enabled: false
+ },
+ bridges : {
+ enabled: false,
+ source: TorBridgeSource.Invalid,
+ builtin_type: null,
+ bridge_strings: [],
+ },
+ proxy: {
+ enabled: false,
+ type: TorProxyType.Invalid,
+ address: null,
+ port: 0,
+ username: null,
+ password: null,
+ },
+ firewall: {
+ enabled: false,
+ allowed_ports: [],
+ },
+ };
+ return settings;
+ },
+
+ /* try and load our settings, and register observers */
+ init: function() {
+ if (TorProtocolService.ownsTorDaemon) {
+ // if the settings branch exists, load settings from prefs
+ if (Services.prefs.getBoolPref(TorSettingsPrefs.enabled, false)) {
+ this.loadFromPrefs();
+ Services.obs.notifyObservers(null, TorSettingsTopics.Ready);
+ }
+ Services.obs.addObserver(this, BrowserTopics.ProfileAfterChange);
+ Services.obs.addObserver(this, TorTopics.ProcessIsReady);
+ }
+ },
+
+ /* wait for relevant life-cycle events to load and/or apply saved settings */
+ observe: async function(subject, topic, data) {
+ console.log(`TorSettings: observed ${topic}`);
+
+ // once the process is ready, we need to apply our settings
+ let handleProcessReady = async () => {
+ Services.obs.removeObserver(this, TorTopics.ProcessIsReady);
+ if (this._settings == null) {
+ // load settings from tor if our load in init() failed and save them to prefs
+ await this.loadLegacy();
+ this.saveToPrefs();
+ } else {
+ // push down settings to tor
+ await this.applySettings();
+ }
+ Services.obs.notifyObservers(null, TorSettingsTopics.Ready);
+ };
+
+ switch (topic) {
+ case BrowserTopics.ProfileAfterChange: {
+ if (TorProtocolService.torProcessStatus == TorProcessStatus.Running) {
+ await handleProcessReady();
+ }
+ }
+ break;
+ case TorTopics.ProcessIsReady: {
+ await handleProcessReady();
+ }
+ break;
+ }
+ },
+
+ // load our settings from old locations (misc prefs and from tor daemon)
+ // TODO: remove this after some time has elapsed to ensure users have migrated to pref settings
+ loadLegacy: async function() {
+ console.log("TorSettings: loadLegacy()");
+
+ let settings = this.defaultSettings();
+
+ /* Quickstart */
+ settings.quickstart.enabled = Services.prefs.getBoolPref(TorLauncherPrefs.quickstart, false);
+
+ /* Bridges
+
+ So the way tor-launcher determines the origin of the configured bridges is a bit
+ weird and depends on inferring our scenario based on some firefox prefs and the
+ relationship between the saved list of bridges in about:config vs the list saved in torrc
+
+ first off, if "extensions.torlauncher.default_bridge_type" is set to one of our
+ builtin default types (obfs4, meek-azure, snowflake, etc) then we provide the
+ bridges in "extensions.torlauncher.default_bridge.*" (filtered by our default_bridge_type)
+
+ next, we compare the list of bridges saved in torrc to the bridges stored in the
+ "extensions.torlauncher.bridgedb_bridge."" branch. If they match *exactly* then we assume
+ the bridges were retrieved from BridgeDB and use those. If the torrc list is empty then we know
+ we have no bridge settings
+
+ finally, if none of the previous conditions are not met, it is assumed the bridges stored in
+ torrc are user-provided
+ */
+
+ let builtinType = Services.prefs.getCharPref(TorLauncherPrefs.default_bridge_type, null);
+
+ // check if source is built-in
+ if (builtinType) {
+ let builtinBridgeStrings = getBuiltinBridgeStrings(builtinType);
+ if (builtinBridgeStrings.length > 0) {
+ settings.bridges.enabled = true;
+ settings.bridges.source = TorBridgeSource.BuiltIn;
+ settings.bridges.builtin_type = builtinType;
+ settings.bridges.bridge_strings = builtinBridgeStrings;
+ }
+ } else {
+ // get our currently configured bridges from tor
+ let torrcBridgeStrings = await (async () => {
+ let bridgeList = await TorProtocolService.readStringArraySetting(TorConfigKeys.bridgeList);
+ let retval = [];
+ for (const line of bridgeList) {
+ let trimmedLine = line.trim();
+ if (trimmedLine) {
+ retval.push(trimmedLine);
+ }
+ }
+ return retval;
+ })();
+
+ // torrc has bridges configured
+ if (torrcBridgeStrings.length > 0) {
+ // compare tor's bridges to our saved bridgedb bridges
+ let bridgedbBBridgeStrings = (() => {
+ let bridgeBranch = Services.prefs.getBranch(TorLauncherPrefs.bridgedb_bridge);
+ let bridgeBranchPrefs = bridgeBranch.getChildList("");
+ // the child prefs do not come in any particular order so sort the keys
+ // so the values can be compared to what we get out off torrc
+ bridgeBranchPrefs.sort();
+
+ // just assume all of the prefs under the parent point to valid bridge string
+ let retval = bridgeBranchPrefs.map(key =>
+ bridgeBranch.getCharPref(key).trim()
+ );
+ return retval;
+ })();
+
+ let arraysEqual = (left, right) => {
+ if (left.length != right.length) {
+ return false;
+ }
+ const length = left.length;
+ for (let i = 0; i < length; ++i) {
+ if (left[i] != right[i]) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ if (arraysEqual(torrcBridgeStrings, bridgedbBBridgeStrings)) {
+ settings.bridges.enabled = true;
+ settings.bridges.source = TorBridgeSource.BridgeDB;
+ settings.bridges.builtin_type = null;
+ settings.bridges.bridge_strings = torrcBridgeStrings;
+ } else {
+ settings.bridges.enabled = true;
+ settings.bridges.source = TorBridgeSource.UserProvided;
+ settings.bridges.builtin_type = null;
+ settings.bridges.bridge_strings = torrcBridgeStrings;
+ }
+ } else {
+ // tor has no bridge strings saved, so bridges not in use
+ settings.bridges.enabled = false;
+ settings.bridges.source = TorBridgeSource.Invalid;
+ settings.bridges.builtin_type = null;
+ settings.bridges.bridge_strings = [];
+ }
+ }
+
+ /* Proxy */
+
+ let proxyString = null;
+ if (proxyString = await TorProtocolService.readStringSetting(TorConfigKeys.socks4Proxy)) {
+ let [address, port] = parseAddrPort(proxyString);
+
+ settings.proxy.enabled = true;
+ settings.proxy.type = TorProxyType.Socks4;
+ settings.proxy.address = address;
+ settings.proxy.port = port;
+ settings.proxy.username = null;
+ settings.proxy.password = null;
+ } else if (proxyString = await TorProtocolService.readStringSetting(TorConfigKeys.socks5Proxy)) {
+ let [address, port] = parseAddrPort(proxyString);
+ let username = await TorProtocolService.readStringSetting(TorConfigKeys.socks5ProxyUsername);
+ let password = await TorProtocolService.readStringSetting(TorConfigKeys.socks5ProxyPassword);
+
+ settings.proxy.enabled = true;
+ settings.proxy.type = TorProxyType.Socks5;
+ settings.proxy.address = address;
+ settings.proxy.port = port;
+ settings.proxy.username = username;
+ settings.proxy.password = password;
+ } else if (proxyString = await TorProtocolService.readStringSetting(TorConfigKeys.httpsProxy)) {
+ let [address, port] = parseAddrPort(proxyString);
+ let authenticator = await TorProtocolService.readStringSetting(TorConfigKeys.httpsProxyAuthenticator);
+ let [username, password] = parseUsernamePassword(authenticator);
+
+ settings.proxy.enabled = true;
+ settings.proxy.type = TorProxyType.HTTPS;
+ settings.proxy.address = address;
+ settings.proxy.port = port;
+ settings.proxy.username = username;
+ settings.proxy.password = password;
+ } else {
+ settings.proxy.enabled = false;
+ settings.proxy.type = TorProxyType.Invalid;
+ settings.proxy.address = null;
+ settings.proxy.port = 0;
+ settings.proxy.username = null;
+ settings.proxy.password = null;
+ }
+
+ /* Firewall */
+ let firewallString = await TorProtocolService.readStringSetting(TorConfigKeys.reachableAddresses);
+ if (firewallString) {
+ let allowedPorts = parseAddrPortList(firewallString);
+ settings.firewall.enabled = allowedPorts.length > 0;
+ settings.firewall.allowed_ports = allowedPorts;
+ } else {
+ settings.firewall.enabled = false;
+ settings.firewall.allowed_ports = [];
+ }
+
+ this._settings = settings;
+
+ return this;
+ },
+
+ // load our settings from prefs
+ loadFromPrefs: function() {
+ console.log("TorSettings: loadFromPrefs()");
+
+ let settings = this.defaultSettings();
+
+ /* Quickstart */
+ settings.quickstart.enabled = Services.prefs.getBoolPref(TorSettingsPrefs.quickstart.enabled);
+ /* Bridges */
+ settings.bridges.enabled = Services.prefs.getBoolPref(TorSettingsPrefs.bridges.enabled);
+ if (settings.bridges.enabled) {
+ settings.bridges.source = Services.prefs.getIntPref(TorSettingsPrefs.bridges.source);
+ // builtin bridge (obfs4, meek, snowlfake, etc)
+ if (settings.bridges.source == TorBridgeSource.BuiltIn) {
+ let builtinType = Services.prefs.getStringPref(TorSettingsPrefs.bridges.builtin_type);
+ settings.bridges.builtin_type = builtinType;
+ // always dynamically load builtin bridges rather than loading the cached versions
+ // if the user upgrades and the builtin bridges have changed, we want to ensure the user
+ // can still bootstrap using the provided bridges
+ let bridgeStrings = getBuiltinBridgeStrings(builtinType);
+ if (bridgeStrings.length > 0) {
+ settings.bridges.bridge_strings = bridgeStrings;
+ } else {
+ // in this case the user is using a builtin bridge that is no longer supported,
+ // reset to settings to default values
+ settings.bridges.enabled = false;
+ settings.bridges.source = TorBridgeSource.Invalid;
+ settings.bridges.builtin_type = null;
+ }
+ } else {
+ settings.bridges.bridge_strings = [];
+ let bridgeBranchPrefs = Services.prefs.getBranch(TorSettingsPrefs.bridges.bridge_strings).getChildList("");
+ bridgeBranchPrefs.forEach(pref => {
+ let bridgeString = Services.prefs.getStringPref(`${TorSettingsPrefs.bridges.bridge_strings}${pref}`);
+ settings.bridges.bridge_strings.push(bridgeString);
+ });
+ }
+ } else {
+ settings.bridges.source = TorBridgeSource.Invalid;
+ settings.bridges.builtin_type = null;
+ settings.bridges.bridge_strings = [];
+ }
+ /* Proxy */
+ settings.proxy.enabled = Services.prefs.getBoolPref(TorSettingsPrefs.proxy.enabled);
+ if (settings.proxy.enabled) {
+ settings.proxy.type = Services.prefs.getIntPref(TorSettingsPrefs.proxy.type);
+ settings.proxy.address = Services.prefs.getStringPref(TorSettingsPrefs.proxy.address);
+ settings.proxy.port = Services.prefs.getIntPref(TorSettingsPrefs.proxy.port);
+ settings.proxy.username = Services.prefs.getStringPref(TorSettingsPrefs.proxy.username);
+ settings.proxy.password = Services.prefs.getStringPref(TorSettingsPrefs.proxy.password);
+ } else {
+ settings.proxy.type = TorProxyType.Invalid;
+ settings.proxy.address = null;
+ settings.proxy.port = 0;
+ settings.proxy.username = null;
+ settings.proxy.password = null;
+ }
+
+ /* Firewall */
+ settings.firewall.enabled = Services.prefs.getBoolPref(TorSettingsPrefs.firewall.enabled);
+ if(settings.firewall.enabled) {
+ let portList = Services.prefs.getStringPref(TorSettingsPrefs.firewall.allowed_ports);
+ settings.firewall.allowed_ports = parsePortList(portList);
+ } else {
+ settings.firewall.allowed_ports = 0;
+ }
+
+ this._settings = settings;
+
+ return this;
+ },
+
+ // save our settings to prefs
+ saveToPrefs: function() {
+ console.log("TorSettings: saveToPrefs()");
+
+ let settings = this._settings;
+
+ /* Quickstart */
+ Services.prefs.setBoolPref(TorSettingsPrefs.quickstart.enabled, settings.quickstart.enabled);
+ /* Bridges */
+ Services.prefs.setBoolPref(TorSettingsPrefs.bridges.enabled, settings.bridges.enabled);
+ if (settings.bridges.enabled) {
+ Services.prefs.setIntPref(TorSettingsPrefs.bridges.source, settings.bridges.source);
+ if (settings.bridges.source === TorBridgeSource.BuiltIn) {
+ Services.prefs.setStringPref(TorSettingsPrefs.bridges.builtin_type, settings.bridges.builtin_type);
+ } else {
+ Services.prefs.clearUserPref(TorSettingsPrefs.bridges.builtin_type);
+ }
+ // erase existing bridge strings
+ let bridgeBranchPrefs = Services.prefs.getBranch(TorSettingsPrefs.bridges.bridge_strings).getChildList("");
+ bridgeBranchPrefs.forEach(pref => {
+ Services.prefs.clearUserPref(`${TorSettingsPrefs.bridges.bridge_strings}${pref}`);
+ });
+ // write new ones
+ settings.bridges.bridge_strings.forEach((string, index) => {
+ Services.prefs.setStringPref(`${TorSettingsPrefs.bridges.bridge_strings}.${index}`, string);
+ });
+ } else {
+ Services.prefs.clearUserPref(TorSettingsPrefs.bridges.source);
+ Services.prefs.clearUserPref(TorSettingsPrefs.bridges.builtin_type);
+ let bridgeBranchPrefs = Services.prefs.getBranch(TorSettingsPrefs.bridges.bridge_strings).getChildList("");
+ bridgeBranchPrefs.forEach(pref => {
+ Services.prefs.clearUserPref(`${TorSettingsPrefs.bridges.bridge_strings}${pref}`);
+ });
+ }
+ /* Proxy */
+ Services.prefs.setBoolPref(TorSettingsPrefs.proxy.enabled, settings.proxy.enabled);
+ if (settings.proxy.enabled) {
+ Services.prefs.setIntPref(TorSettingsPrefs.proxy.type, settings.proxy.type);
+ Services.prefs.setStringPref(TorSettingsPrefs.proxy.address, settings.proxy.address);
+ Services.prefs.setIntPref(TorSettingsPrefs.proxy.port, settings.proxy.port);
+ Services.prefs.setStringPref(TorSettingsPrefs.proxy.username, settings.proxy.username);
+ Services.prefs.setStringPref(TorSettingsPrefs.proxy.password, settings.proxy.password);
+ } else {
+ Services.prefs.clearUserPref(TorSettingsPrefs.proxy.type);
+ Services.prefs.clearUserPref(TorSettingsPrefs.proxy.address);
+ Services.prefs.clearUserPref(TorSettingsPrefs.proxy.port);
+ Services.prefs.clearUserPref(TorSettingsPrefs.proxy.username);
+ Services.prefs.clearUserPref(TorSettingsPrefs.proxy.password);
+ }
+ /* Firewall */
+ Services.prefs.setBoolPref(TorSettingsPrefs.firewall.enabled, settings.firewall.enabled);
+ if (settings.firewall.enabled) {
+ Services.prefs.setStringPref(TorSettingsPrefs.firewall.allowed_ports, settings.firewall.allowed_ports.join(","));
+ } else {
+ Services.prefs.clearUserPref(TorSettingsPrefs.firewall.allowed_ports);
+ }
+
+ // all tor settings now stored in prefs :)
+ Services.prefs.setBoolPref(TorSettingsPrefs.enabled, true);
+
+ return this;
+ },
+
+ // push our settings down to the tor daemon
+ applySettings: async function() {
+ console.log("TorSettings: applySettings()");
+ let settings = this._settings;
+ let settingsMap = new Map();
+
+ /* Bridges */
+ settingsMap.set(TorConfigKeys.useBridges, settings.bridges.enabled);
+ if (settings.bridges.enabled) {
+ settingsMap.set(TorConfigKeys.bridgeList, settings.bridges.bridge_strings);
+ } else {
+ // shuffle bridge list
+ settingsMap.set(TorConfigKeys.bridgeList, null);
+ }
+
+ /* Proxy */
+ settingsMap.set(TorConfigKeys.socks4Proxy, null);
+ settingsMap.set(TorConfigKeys.socks5Proxy, null);
+ settingsMap.set(TorConfigKeys.socks5ProxyUsername, null);
+ settingsMap.set(TorConfigKeys.socks5ProxyPassword, null);
+ settingsMap.set(TorConfigKeys.httpsProxy, null);
+ settingsMap.set(TorConfigKeys.httpsProxyAuthenticator, null);
+ if (settings.proxy.enabled) {
+ let address = settings.proxy.address;
+ let port = settings.proxy.port;
+ let username = settings.proxy.username;
+ let password = settings.proxy.password;
+
+ switch (settings.proxy.type) {
+ case TorProxyType.Socks4:
+ settingsMap.set(TorConfigKeys.socks4Proxy, `${address}:${port}`);
+ break;
+ case TorProxyType.Socks5:
+ settingsMap.set(TorConfigKeys.socks5Proxy, `${address}:${port}`);
+ settingsMap.set(TorConfigKeys.socks5ProxyUsername, username);
+ settingsMap.set(TorConfigKeys.socks5ProxyPassword, password);
+ break;
+ case TorProxyType.HTTPS:
+ settingsMap.set(TorConfigKeys.httpsProxy, `${address}:${port}`);
+ settingsMap.set(TorConfigKeys.httpsProxyAuthenticator, `${username}:${password}`);
+ break;
+ }
+ }
+
+ /* Firewall */
+ if (settings.firewall.enabled) {
+ let reachableAddresses = settings.firewall.allowed_ports.map(port => `*:${port}`).join(",");
+ settingsMap.set(TorConfigKeys.reachableAddresses, reachableAddresses);
+ } else {
+ settingsMap.set(TorConfigKeys.reachableAddresses, null);
+ }
+
+ /* Push to Tor */
+ await TorProtocolService.writeSettings(settingsMap);
+
+ return this;
+ },
+
+ /* Getters and Setters */
+
+
+ // Quickstart
+ get quickstart() {
+ return {
+ // Avoid a race-condition on first-start where this property
+ // may be accessed before `self._settings` is initialized.
+ // This work-around can be removed when #40598 is resolved.
+ get enabled() { return (self._settings ? self._settings.quickstart.enabled : false); },
+ set enabled(val) {
+ if (val != self._settings.quickstart.enabled)
+ {
+ self._settings.quickstart.enabled = val;
+ Services.obs.notifyObservers({value: val}, TorSettingsTopics.SettingChanged, TorSettingsData.QuickStartEnabled);
+ }
+ },
+ };
+ },
+
+ // Bridges
+ get bridges() {
+ return {
+ get enabled() { return self._settings.bridges.enabled; },
+ set enabled(val) {
+ self._settings.bridges.enabled = val;
+ // reset bridge settings
+ self._settings.bridges.source = TorBridgeSource.Invalid;
+ self._settings.bridges.builtin_type = null;
+ self._settings.bridges.bridge_strings = [];
+ },
+ get source() { return self._settings.bridges.source; },
+ set source(val) { self._settings.bridges.source = val; },
+ get builtin_type() { return self._settings.bridges.builtin_type; },
+ set builtin_type(val) {
+ let bridgeStrings = getBuiltinBridgeStrings(val);
+ if (bridgeStrings.length > 0) {
+ self._settings.bridges.builtin_type = val;
+ self._settings.bridges.bridge_strings = bridgeStrings;
+ }
+ },
+ get bridge_strings() { return arrayCopy(self._settings.bridges.bridge_strings); },
+ set bridge_strings(val) {
+ self._settings.bridges.bridge_strings = parseBridgeStrings(val);
+ },
+ };
+ },
+
+ // Proxy
+ get proxy() {
+ return {
+ get enabled() { return self._settings.proxy.enabled; },
+ set enabled(val) {
+ self._settings.proxy.enabled = val;
+ // reset proxy settings
+ self._settings.proxy.type = TorProxyType.Invalid;
+ self._settings.proxy.address = null;
+ self._settings.proxy.port = 0;
+ self._settings.proxy.username = null;
+ self._settings.proxy.password = null;
+ },
+ get type() { return self._settings.proxy.type; },
+ set type(val) { self._settings.proxy.type = val; },
+ get address() { return self._settings.proxy.address; },
+ set address(val) { self._settings.proxy.address = val; },
+ get port() { return arrayCopy(self._settings.proxy.port); },
+ set port(val) { self._settings.proxy.port = parsePort(val); },
+ get username() { return self._settings.proxy.username; },
+ set username(val) { self._settings.proxy.username = val; },
+ get password() { return self._settings.proxy.password; },
+ set password(val) { self._settings.proxy.password = val; },
+ get uri() {
+ switch (this.type) {
+ case TorProxyType.Socks4:
+ return `socks4a://${this.address}:${this.port}`;
+ case TorProxyType.Socks5:
+ if (this.username) {
+ return `socks5://${this.username}:${this.password}@${this.address}:${this.port}`;
+ }
+ return `socks5://${this.address}:${this.port}`;
+ case TorProxyType.HTTPS:
+ if (this._proxyUsername) {
+ return `http://${this.username}:${this.password}@${this.address}:${this.port}`;
+ }
+ return `http://${this.address}:${this.port}`;
+ }
+ return null;
+ },
+ };
+ },
+
+ // Firewall
+ get firewall() {
+ return {
+ get enabled() { return self._settings.firewall.enabled; },
+ set enabled(val) {
+ self._settings.firewall.enabled = val;
+ // reset firewall settings
+ self._settings.firewall.allowed_ports = [];
+ },
+ get allowed_ports() { return self._settings.firewall.allowed_ports; },
+ set allowed_ports(val) { self._settings.firewall.allowed_ports = parsePortList(val); },
+ };
+ },
+ };
+ self.init();
+ return self;
+})();
diff --git a/browser/modules/moz.build b/browser/modules/moz.build
index 1ea57aba1a93..8c001d4ac6ed 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -156,6 +156,7 @@ EXTRA_JS_MODULES += [
'TorConnect.jsm',
'TorProcessService.jsm',
"TorProtocolService.jsm",
+ "TorSettings.jsm",
"TorStrings.jsm",
"TransientPrefs.jsm",
"webrtcUI.jsm",
diff --git a/toolkit/components/processsingleton/MainProcessSingleton.jsm b/toolkit/components/processsingleton/MainProcessSingleton.jsm
index 62afa98e1ffc..ba8cd0f3f97d 100644
--- a/toolkit/components/processsingleton/MainProcessSingleton.jsm
+++ b/toolkit/components/processsingleton/MainProcessSingleton.jsm
@@ -24,6 +24,11 @@ MainProcessSingleton.prototype = {
null
);
+ ChromeUtils.import(
+ "resource:///modules/TorSettings.jsm",
+ null
+ );
+
ChromeUtils.import(
"resource:///modules/TorConnect.jsm",
null
diff --git a/toolkit/modules/AsyncPrefs.jsm b/toolkit/modules/AsyncPrefs.jsm
index f7d867e47dc0..2834c484c919 100644
--- a/toolkit/modules/AsyncPrefs.jsm
+++ b/toolkit/modules/AsyncPrefs.jsm
@@ -20,7 +20,6 @@ const kAllowedPrefs = new Set([
"browser.contentblocking.report.hide_vpn_banner",
"browser.contentblocking.report.show_mobile_app",
- "extensions.torlauncher.quickstart",
"narrate.rate",
"narrate.voice",
1
0